mirror of
https://github.com/Eugeny/tabby
synced 2024-12-16 00:02:53 +00:00
4100 lines
308 KiB
HTML
4100 lines
308 KiB
HTML
<html>
|
||
<meta charset="utf-8"/>
|
||
|
||
<!-- ----------------------------------------------------- -->
|
||
<head>
|
||
<title>Clink v1.2.9</title>
|
||
<style>
|
||
@import url('https://fonts.googleapis.com/css2?family=Rambla:wght@400;700&family=Roboto&family=Fira+Mono&display=swap');
|
||
html {
|
||
font: 12pt Roboto,Calibri,Arial,Helvetica,sans-serif;
|
||
-ms-text-size-adjust: 100%;
|
||
-webkit-text-size-adjust: 100%;
|
||
}
|
||
|
||
body {
|
||
padding-top: 3rem;
|
||
width: 90%;
|
||
margin: 0 auto;
|
||
}
|
||
|
||
h1, h2, h3, h4, h5, h6, dt { font-family: Rambla,Roboto,Calibri,Arial,Helvetica,sans-serif }
|
||
|
||
h1 {
|
||
width: 100%;
|
||
padding: 2rem 0 0 0;
|
||
border-bottom: 0.15rem #3377cc solid;
|
||
font-size: 2rem;
|
||
}
|
||
|
||
h2 { font-size: 1.60rem; }
|
||
h3 { font-size: 1.40rem; }
|
||
h4 { font-size: 1.20rem; }
|
||
h5 { font-size: 1.10rem; }
|
||
h6 { font-size: 1.00rem; }
|
||
|
||
dt {
|
||
font-family: Rambla,Roboto,Calibri,Arial,Helvetica,sans-serif;
|
||
font-weight: 700;
|
||
padding: 0 0 0.4rem 0;
|
||
}
|
||
|
||
blockquote {
|
||
display: block;
|
||
padding: 0.1rem 1rem 0.1rem 1rem;
|
||
margin: 0 0 1rem 0.4rem;
|
||
box-shadow: 0.1rem 0.1rem 0.4rem #ccc;
|
||
border-left-width: 0.4rem;
|
||
border-left-style: solid;
|
||
border-color: #3377cc;
|
||
}
|
||
|
||
fieldset {
|
||
display: block;
|
||
padding: 0.5rem 0.5rem 1rem 1rem;
|
||
margin: 0 0 1rem;
|
||
box-shadow: 0.1rem 0.1rem 0.4rem #ccc;
|
||
border-radius: 0.4rem;
|
||
border-style: solid;
|
||
border-width: 0.15rem;
|
||
border-color: #990000;
|
||
background: #ffffee;
|
||
}
|
||
|
||
legend {
|
||
font-weight: 600;
|
||
padding: 0 0.3rem;
|
||
}
|
||
|
||
code {
|
||
display: inline-block;
|
||
font-family: "Fira Mono",monospace;
|
||
font-size: 0.9rem;
|
||
padding: 0px 0.2rem;
|
||
margin: auto 0px;
|
||
background-color: #eee;
|
||
border: 1px solid #ddd;
|
||
border-radius: 0.2rem;
|
||
}
|
||
|
||
pre {
|
||
margin: 0.15rem 0.5rem;
|
||
padding: 0;
|
||
}
|
||
|
||
pre code {
|
||
border: none;
|
||
padding: 8px;
|
||
border-radius: inherit;
|
||
}
|
||
|
||
kbd {
|
||
padding:1px 0.3rem;
|
||
border-collapse:separate;
|
||
border:0.05rem solid #ccc;
|
||
font:0.8rem SFMono-Regular,Consolas,Liberation Mono,Menlo,monospace;
|
||
background-color:#f8f8f8;
|
||
color:#333;
|
||
-moz-box-shadow:0 0.05rem 0px rgba(0, 0, 0, 0.2),0 0 0 0px #ffffff inset;
|
||
-webkit-box-shadow:0 0.05rem 0px rgba(0, 0, 0, 0.2),0 0 0 0px #ffffff inset;
|
||
box-shadow:0 0.05rem 0px rgba(0, 0, 0, 0.2),0 0 0 0px #ffffff inset;
|
||
-moz-border-radius:0.3rem;
|
||
-webkit-border-radius:0.3rem;
|
||
border-radius:0.3rem;
|
||
display:inline-block;
|
||
margin:0 0.1rem;
|
||
vertical-align:middle;
|
||
transform:translateY(-5%);
|
||
white-space:nowrap;
|
||
}
|
||
|
||
#content td:nth-child(1) {
|
||
white-space: nowrap;
|
||
}
|
||
|
||
#content td:nth-child(1) code {
|
||
border: none;
|
||
padding: 0 0 0 0;
|
||
border-radius: 0;
|
||
background-color: transparent;
|
||
}
|
||
|
||
.section {
|
||
}
|
||
|
||
.deprecated {
|
||
opacity: 0.5;
|
||
}
|
||
|
||
.comment-web-link {
|
||
font-style: italic;
|
||
}
|
||
|
||
.colorsample {
|
||
display:inline-block;
|
||
border:1px solid lightgray;
|
||
width:0.8rem;
|
||
height:0.8rem;
|
||
vertical-align:middle;
|
||
}
|
||
|
||
#header {
|
||
float: right;
|
||
text-align: right;
|
||
}
|
||
|
||
#header #title {
|
||
font: 2.5rem Rambla,Roboto,Calibri,Arial,Helvetica,sans-serif;
|
||
font-weight: bold;
|
||
margin-bottom: 0.4rem;
|
||
}
|
||
|
||
#content {
|
||
clear: both;
|
||
}
|
||
|
||
#content table {
|
||
font-size: 1rem;
|
||
margin: auto 5%;
|
||
border-collapse: collapse;
|
||
}
|
||
|
||
#content pre, #api .show {
|
||
border: 1px solid #ddd;
|
||
border-radius: 0.4rem;
|
||
background-color: #eee;
|
||
}
|
||
|
||
#content td, #content th {
|
||
vertical-align: text-top;
|
||
padding: 0.2rem 0.5rem;
|
||
}
|
||
|
||
#content th {
|
||
background-color: #fff;
|
||
}
|
||
|
||
#content td {
|
||
border: 1px solid #ddd;
|
||
}
|
||
|
||
#content tr:nth-child(odd) {
|
||
background-color: #fbfbfb;
|
||
}
|
||
|
||
#content tr:nth-child(even) {
|
||
background-color: #fff;
|
||
}
|
||
|
||
#content hr {
|
||
border: 0;
|
||
height: 1px;
|
||
background-image: linear-gradient(to right, rgba(0,0,0,0), rgba(0,0,0,0.3), rgba(0,0,0,0.3), rgba(0,0,0,0.3), rgba(0,0,0,0));
|
||
width: 80%;
|
||
}
|
||
|
||
#content .arg {
|
||
white-space: nowrap;
|
||
font-family: "Fira Mono",monospace;
|
||
font-style: italic;
|
||
font-size: 95%;
|
||
opacity: 75%;
|
||
padding-left: 0.125rem;
|
||
padding-right: 0.125rem;
|
||
}
|
||
|
||
#content .arg_name {
|
||
font-weight: bold;
|
||
}
|
||
|
||
#content .tablescheme {
|
||
white-space: nowrap;
|
||
font-family: "Fira Mono",monospace;
|
||
font-style: italic;
|
||
font-size: 95%;
|
||
opacity: 75%;
|
||
padding-left: 0.125rem;
|
||
padding-right: 0.125rem;
|
||
}
|
||
|
||
#content ol li {
|
||
padding-left: 0.5rem;
|
||
}
|
||
|
||
#content #api .group {
|
||
margin-bottom: 1rem;
|
||
}
|
||
|
||
#content #api .body {
|
||
margin-left: 1rem;
|
||
}
|
||
|
||
#content #api .header .name {
|
||
font-weight: bold;
|
||
float: left;
|
||
width: 40%;
|
||
}
|
||
|
||
#content #api .header .signature {
|
||
text-align: right;
|
||
}
|
||
|
||
#content #api .group_name {
|
||
font-size: 1.1rem;
|
||
font-weight: bold;
|
||
}
|
||
|
||
#content #api .function {
|
||
margin-left: 2rem;
|
||
margin-bottom: 1.0rem;
|
||
}
|
||
|
||
#content #api .show {
|
||
white-space: pre;
|
||
font-family: "Fira Mono",monospace;
|
||
}
|
||
|
||
[class^="hljs"] {
|
||
font-family: "Fira Mono",monospace;
|
||
}
|
||
/*
|
||
|
||
Atom One Light by Daniel Gamage
|
||
Original One Light Syntax theme from https://github.com/atom/one-light-syntax
|
||
|
||
base: #fafafa
|
||
mono-1: #383a42
|
||
mono-2: #686b77
|
||
mono-3: #a0a1a7
|
||
hue-1: #0184bb
|
||
hue-2: #4078f2
|
||
hue-3: #a626a4
|
||
hue-4: #50a14f
|
||
hue-5: #e45649
|
||
hue-5-2: #c91243
|
||
hue-6: #986801
|
||
hue-6-2: #c18401
|
||
|
||
*/
|
||
|
||
.hljs {
|
||
display: block;
|
||
overflow-x: auto;
|
||
padding: 0.5em;
|
||
color: #383a42;
|
||
background: #fafafa;
|
||
}
|
||
|
||
.hljs-comment,
|
||
.hljs-quote {
|
||
color: #a0a1a7;
|
||
font-style: italic;
|
||
}
|
||
|
||
.hljs-doctag,
|
||
.hljs-keyword,
|
||
.hljs-formula {
|
||
color: #a626a4;
|
||
}
|
||
|
||
.hljs-section,
|
||
.hljs-name,
|
||
.hljs-selector-tag,
|
||
.hljs-deletion,
|
||
.hljs-subst {
|
||
color: #e45649;
|
||
}
|
||
|
||
.hljs-literal {
|
||
color: #0184bb;
|
||
}
|
||
|
||
.hljs-string,
|
||
.hljs-regexp,
|
||
.hljs-addition,
|
||
.hljs-attribute,
|
||
.hljs-meta-string {
|
||
color: #50a14f;
|
||
}
|
||
|
||
.hljs-built_in,
|
||
.hljs-class .hljs-title {
|
||
color: #c18401;
|
||
}
|
||
|
||
.hljs-attr,
|
||
.hljs-variable,
|
||
.hljs-template-variable,
|
||
.hljs-type,
|
||
.hljs-selector-class,
|
||
.hljs-selector-attr,
|
||
.hljs-selector-pseudo,
|
||
.hljs-number {
|
||
color: #986801;
|
||
}
|
||
|
||
.hljs-symbol,
|
||
.hljs-bullet,
|
||
.hljs-link,
|
||
.hljs-meta,
|
||
.hljs-selector-id,
|
||
.hljs-title {
|
||
color: #4078f2;
|
||
}
|
||
|
||
.hljs-emphasis {
|
||
font-style: italic;
|
||
}
|
||
|
||
.hljs-strong {
|
||
font-weight: bold;
|
||
}
|
||
|
||
.hljs-link {
|
||
text-decoration: underline;
|
||
}
|
||
</style>
|
||
<script type="text/javascript">
|
||
/*
|
||
Highlight.js 10.7.2 (00233d63)
|
||
License: BSD-3-Clause
|
||
Copyright (c) 2006-2021, Ivan Sagalaev
|
||
*/
|
||
var hljs=function(){"use strict";function e(t){
|
||
return t instanceof Map?t.clear=t.delete=t.set=()=>{
|
||
throw Error("map is read-only")}:t instanceof Set&&(t.add=t.clear=t.delete=()=>{
|
||
throw Error("set is read-only")
|
||
}),Object.freeze(t),Object.getOwnPropertyNames(t).forEach((n=>{var i=t[n]
|
||
;"object"!=typeof i||Object.isFrozen(i)||e(i)})),t}var t=e,n=e;t.default=n
|
||
;class i{constructor(e){
|
||
void 0===e.data&&(e.data={}),this.data=e.data,this.isMatchIgnored=!1}
|
||
ignoreMatch(){this.isMatchIgnored=!0}}function s(e){
|
||
return e.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"'")
|
||
}function a(e,...t){const n=Object.create(null);for(const t in e)n[t]=e[t]
|
||
;return t.forEach((e=>{for(const t in e)n[t]=e[t]})),n}const r=e=>!!e.kind
|
||
;class l{constructor(e,t){
|
||
this.buffer="",this.classPrefix=t.classPrefix,e.walk(this)}addText(e){
|
||
this.buffer+=s(e)}openNode(e){if(!r(e))return;let t=e.kind
|
||
;e.sublanguage||(t=`${this.classPrefix}${t}`),this.span(t)}closeNode(e){
|
||
r(e)&&(this.buffer+="</span>")}value(){return this.buffer}span(e){
|
||
this.buffer+=`<span class="${e}">`}}class o{constructor(){this.rootNode={
|
||
children:[]},this.stack=[this.rootNode]}get top(){
|
||
return this.stack[this.stack.length-1]}get root(){return this.rootNode}add(e){
|
||
this.top.children.push(e)}openNode(e){const t={kind:e,children:[]}
|
||
;this.add(t),this.stack.push(t)}closeNode(){
|
||
if(this.stack.length>1)return this.stack.pop()}closeAllNodes(){
|
||
for(;this.closeNode(););}toJSON(){return JSON.stringify(this.rootNode,null,4)}
|
||
walk(e){return this.constructor._walk(e,this.rootNode)}static _walk(e,t){
|
||
return"string"==typeof t?e.addText(t):t.children&&(e.openNode(t),
|
||
t.children.forEach((t=>this._walk(e,t))),e.closeNode(t)),e}static _collapse(e){
|
||
"string"!=typeof e&&e.children&&(e.children.every((e=>"string"==typeof e))?e.children=[e.children.join("")]:e.children.forEach((e=>{
|
||
o._collapse(e)})))}}class c extends o{constructor(e){super(),this.options=e}
|
||
addKeyword(e,t){""!==e&&(this.openNode(t),this.addText(e),this.closeNode())}
|
||
addText(e){""!==e&&this.add(e)}addSublanguage(e,t){const n=e.root
|
||
;n.kind=t,n.sublanguage=!0,this.add(n)}toHTML(){
|
||
return new l(this,this.options).value()}finalize(){return!0}}function g(e){
|
||
return e?"string"==typeof e?e:e.source:null}
|
||
const u=/\[(?:[^\\\]]|\\.)*\]|\(\??|\\([1-9][0-9]*)|\\./,h="[a-zA-Z]\\w*",d="[a-zA-Z_]\\w*",f="\\b\\d+(\\.\\d+)?",p="(-?)(\\b0[xX][a-fA-F0-9]+|(\\b\\d+(\\.\\d*)?|\\.\\d+)([eE][-+]?\\d+)?)",m="\\b(0b[01]+)",b={
|
||
begin:"\\\\[\\s\\S]",relevance:0},E={className:"string",begin:"'",end:"'",
|
||
illegal:"\\n",contains:[b]},x={className:"string",begin:'"',end:'"',
|
||
illegal:"\\n",contains:[b]},v={
|
||
begin:/\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\b/
|
||
},w=(e,t,n={})=>{const i=a({className:"comment",begin:e,end:t,contains:[]},n)
|
||
;return i.contains.push(v),i.contains.push({className:"doctag",
|
||
begin:"(?:TODO|FIXME|NOTE|BUG|OPTIMIZE|HACK|XXX):",relevance:0}),i
|
||
},y=w("//","$"),N=w("/\\*","\\*/"),R=w("#","$");var _=Object.freeze({
|
||
__proto__:null,MATCH_NOTHING_RE:/\b\B/,IDENT_RE:h,UNDERSCORE_IDENT_RE:d,
|
||
NUMBER_RE:f,C_NUMBER_RE:p,BINARY_NUMBER_RE:m,
|
||
RE_STARTERS_RE:"!|!=|!==|%|%=|&|&&|&=|\\*|\\*=|\\+|\\+=|,|-|-=|/=|/|:|;|<<|<<=|<=|<|===|==|=|>>>=|>>=|>=|>>>|>>|>|\\?|\\[|\\{|\\(|\\^|\\^=|\\||\\|=|\\|\\||~",
|
||
SHEBANG:(e={})=>{const t=/^#![ ]*\//
|
||
;return e.binary&&(e.begin=((...e)=>e.map((e=>g(e))).join(""))(t,/.*\b/,e.binary,/\b.*/)),
|
||
a({className:"meta",begin:t,end:/$/,relevance:0,"on:begin":(e,t)=>{
|
||
0!==e.index&&t.ignoreMatch()}},e)},BACKSLASH_ESCAPE:b,APOS_STRING_MODE:E,
|
||
QUOTE_STRING_MODE:x,PHRASAL_WORDS_MODE:v,COMMENT:w,C_LINE_COMMENT_MODE:y,
|
||
C_BLOCK_COMMENT_MODE:N,HASH_COMMENT_MODE:R,NUMBER_MODE:{className:"number",
|
||
begin:f,relevance:0},C_NUMBER_MODE:{className:"number",begin:p,relevance:0},
|
||
BINARY_NUMBER_MODE:{className:"number",begin:m,relevance:0},CSS_NUMBER_MODE:{
|
||
className:"number",
|
||
begin:f+"(%|em|ex|ch|rem|vw|vh|vmin|vmax|cm|mm|in|pt|pc|px|deg|grad|rad|turn|s|ms|Hz|kHz|dpi|dpcm|dppx)?",
|
||
relevance:0},REGEXP_MODE:{begin:/(?=\/[^/\n]*\/)/,contains:[{className:"regexp",
|
||
begin:/\//,end:/\/[gimuy]*/,illegal:/\n/,contains:[b,{begin:/\[/,end:/\]/,
|
||
relevance:0,contains:[b]}]}]},TITLE_MODE:{className:"title",begin:h,relevance:0
|
||
},UNDERSCORE_TITLE_MODE:{className:"title",begin:d,relevance:0},METHOD_GUARD:{
|
||
begin:"\\.\\s*[a-zA-Z_]\\w*",relevance:0},END_SAME_AS_BEGIN:e=>Object.assign(e,{
|
||
"on:begin":(e,t)=>{t.data._beginMatch=e[1]},"on:end":(e,t)=>{
|
||
t.data._beginMatch!==e[1]&&t.ignoreMatch()}})});function k(e,t){
|
||
"."===e.input[e.index-1]&&t.ignoreMatch()}function M(e,t){
|
||
t&&e.beginKeywords&&(e.begin="\\b("+e.beginKeywords.split(" ").join("|")+")(?!\\.)(?=\\b|\\s)",
|
||
e.__beforeBegin=k,e.keywords=e.keywords||e.beginKeywords,delete e.beginKeywords,
|
||
void 0===e.relevance&&(e.relevance=0))}function O(e,t){
|
||
Array.isArray(e.illegal)&&(e.illegal=((...e)=>"("+e.map((e=>g(e))).join("|")+")")(...e.illegal))
|
||
}function A(e,t){if(e.match){
|
||
if(e.begin||e.end)throw Error("begin & end are not supported with match")
|
||
;e.begin=e.match,delete e.match}}function L(e,t){
|
||
void 0===e.relevance&&(e.relevance=1)}
|
||
const I=["of","and","for","in","not","or","if","then","parent","list","value"]
|
||
;function j(e,t,n="keyword"){const i={}
|
||
;return"string"==typeof e?s(n,e.split(" ")):Array.isArray(e)?s(n,e):Object.keys(e).forEach((n=>{
|
||
Object.assign(i,j(e[n],t,n))})),i;function s(e,n){
|
||
t&&(n=n.map((e=>e.toLowerCase()))),n.forEach((t=>{const n=t.split("|")
|
||
;i[n[0]]=[e,B(n[0],n[1])]}))}}function B(e,t){
|
||
return t?Number(t):(e=>I.includes(e.toLowerCase()))(e)?0:1}
|
||
function T(e,{plugins:t}){function n(t,n){
|
||
return RegExp(g(t),"m"+(e.case_insensitive?"i":"")+(n?"g":""))}class i{
|
||
constructor(){
|
||
this.matchIndexes={},this.regexes=[],this.matchAt=1,this.position=0}
|
||
addRule(e,t){
|
||
t.position=this.position++,this.matchIndexes[this.matchAt]=t,this.regexes.push([t,e]),
|
||
this.matchAt+=(e=>RegExp(e.toString()+"|").exec("").length-1)(e)+1}compile(){
|
||
0===this.regexes.length&&(this.exec=()=>null)
|
||
;const e=this.regexes.map((e=>e[1]));this.matcherRe=n(((e,t="|")=>{let n=0
|
||
;return e.map((e=>{n+=1;const t=n;let i=g(e),s="";for(;i.length>0;){
|
||
const e=u.exec(i);if(!e){s+=i;break}
|
||
s+=i.substring(0,e.index),i=i.substring(e.index+e[0].length),
|
||
"\\"===e[0][0]&&e[1]?s+="\\"+(Number(e[1])+t):(s+=e[0],"("===e[0]&&n++)}return s
|
||
})).map((e=>`(${e})`)).join(t)})(e),!0),this.lastIndex=0}exec(e){
|
||
this.matcherRe.lastIndex=this.lastIndex;const t=this.matcherRe.exec(e)
|
||
;if(!t)return null
|
||
;const n=t.findIndex(((e,t)=>t>0&&void 0!==e)),i=this.matchIndexes[n]
|
||
;return t.splice(0,n),Object.assign(t,i)}}class s{constructor(){
|
||
this.rules=[],this.multiRegexes=[],
|
||
this.count=0,this.lastIndex=0,this.regexIndex=0}getMatcher(e){
|
||
if(this.multiRegexes[e])return this.multiRegexes[e];const t=new i
|
||
;return this.rules.slice(e).forEach((([e,n])=>t.addRule(e,n))),
|
||
t.compile(),this.multiRegexes[e]=t,t}resumingScanAtSamePosition(){
|
||
return 0!==this.regexIndex}considerAll(){this.regexIndex=0}addRule(e,t){
|
||
this.rules.push([e,t]),"begin"===t.type&&this.count++}exec(e){
|
||
const t=this.getMatcher(this.regexIndex);t.lastIndex=this.lastIndex
|
||
;let n=t.exec(e)
|
||
;if(this.resumingScanAtSamePosition())if(n&&n.index===this.lastIndex);else{
|
||
const t=this.getMatcher(0);t.lastIndex=this.lastIndex+1,n=t.exec(e)}
|
||
return n&&(this.regexIndex+=n.position+1,
|
||
this.regexIndex===this.count&&this.considerAll()),n}}
|
||
if(e.compilerExtensions||(e.compilerExtensions=[]),
|
||
e.contains&&e.contains.includes("self"))throw Error("ERR: contains `self` is not supported at the top-level of a language. See documentation.")
|
||
;return e.classNameAliases=a(e.classNameAliases||{}),function t(i,r){const l=i
|
||
;if(i.isCompiled)return l
|
||
;[A].forEach((e=>e(i,r))),e.compilerExtensions.forEach((e=>e(i,r))),
|
||
i.__beforeBegin=null,[M,O,L].forEach((e=>e(i,r))),i.isCompiled=!0;let o=null
|
||
;if("object"==typeof i.keywords&&(o=i.keywords.$pattern,
|
||
delete i.keywords.$pattern),
|
||
i.keywords&&(i.keywords=j(i.keywords,e.case_insensitive)),
|
||
i.lexemes&&o)throw Error("ERR: Prefer `keywords.$pattern` to `mode.lexemes`, BOTH are not allowed. (see mode reference) ")
|
||
;return o=o||i.lexemes||/\w+/,
|
||
l.keywordPatternRe=n(o,!0),r&&(i.begin||(i.begin=/\B|\b/),
|
||
l.beginRe=n(i.begin),i.endSameAsBegin&&(i.end=i.begin),
|
||
i.end||i.endsWithParent||(i.end=/\B|\b/),
|
||
i.end&&(l.endRe=n(i.end)),l.terminatorEnd=g(i.end)||"",
|
||
i.endsWithParent&&r.terminatorEnd&&(l.terminatorEnd+=(i.end?"|":"")+r.terminatorEnd)),
|
||
i.illegal&&(l.illegalRe=n(i.illegal)),
|
||
i.contains||(i.contains=[]),i.contains=[].concat(...i.contains.map((e=>(e=>(e.variants&&!e.cachedVariants&&(e.cachedVariants=e.variants.map((t=>a(e,{
|
||
variants:null},t)))),e.cachedVariants?e.cachedVariants:S(e)?a(e,{
|
||
starts:e.starts?a(e.starts):null
|
||
}):Object.isFrozen(e)?a(e):e))("self"===e?i:e)))),i.contains.forEach((e=>{t(e,l)
|
||
})),i.starts&&t(i.starts,r),l.matcher=(e=>{const t=new s
|
||
;return e.contains.forEach((e=>t.addRule(e.begin,{rule:e,type:"begin"
|
||
}))),e.terminatorEnd&&t.addRule(e.terminatorEnd,{type:"end"
|
||
}),e.illegal&&t.addRule(e.illegal,{type:"illegal"}),t})(l),l}(e)}function S(e){
|
||
return!!e&&(e.endsWithParent||S(e.starts))}function P(e){const t={
|
||
props:["language","code","autodetect"],data:()=>({detectedLanguage:"",
|
||
unknownLanguage:!1}),computed:{className(){
|
||
return this.unknownLanguage?"":"hljs "+this.detectedLanguage},highlighted(){
|
||
if(!this.autoDetect&&!e.getLanguage(this.language))return console.warn(`The language "${this.language}" you specified could not be found.`),
|
||
this.unknownLanguage=!0,s(this.code);let t={}
|
||
;return this.autoDetect?(t=e.highlightAuto(this.code),
|
||
this.detectedLanguage=t.language):(t=e.highlight(this.language,this.code,this.ignoreIllegals),
|
||
this.detectedLanguage=this.language),t.value},autoDetect(){
|
||
return!(this.language&&(e=this.autodetect,!e&&""!==e));var e},
|
||
ignoreIllegals:()=>!0},render(e){return e("pre",{},[e("code",{
|
||
class:this.className,domProps:{innerHTML:this.highlighted}})])}};return{
|
||
Component:t,VuePlugin:{install(e){e.component("highlightjs",t)}}}}const D={
|
||
"after:highlightElement":({el:e,result:t,text:n})=>{const i=H(e)
|
||
;if(!i.length)return;const a=document.createElement("div")
|
||
;a.innerHTML=t.value,t.value=((e,t,n)=>{let i=0,a="";const r=[];function l(){
|
||
return e.length&&t.length?e[0].offset!==t[0].offset?e[0].offset<t[0].offset?e:t:"start"===t[0].event?e:t:e.length?e:t
|
||
}function o(e){a+="<"+C(e)+[].map.call(e.attributes,(function(e){
|
||
return" "+e.nodeName+'="'+s(e.value)+'"'})).join("")+">"}function c(e){
|
||
a+="</"+C(e)+">"}function g(e){("start"===e.event?o:c)(e.node)}
|
||
for(;e.length||t.length;){let t=l()
|
||
;if(a+=s(n.substring(i,t[0].offset)),i=t[0].offset,t===e){r.reverse().forEach(c)
|
||
;do{g(t.splice(0,1)[0]),t=l()}while(t===e&&t.length&&t[0].offset===i)
|
||
;r.reverse().forEach(o)
|
||
}else"start"===t[0].event?r.push(t[0].node):r.pop(),g(t.splice(0,1)[0])}
|
||
return a+s(n.substr(i))})(i,H(a),n)}};function C(e){
|
||
return e.nodeName.toLowerCase()}function H(e){const t=[];return function e(n,i){
|
||
for(let s=n.firstChild;s;s=s.nextSibling)3===s.nodeType?i+=s.nodeValue.length:1===s.nodeType&&(t.push({
|
||
event:"start",offset:i,node:s}),i=e(s,i),C(s).match(/br|hr|img|input/)||t.push({
|
||
event:"stop",offset:i,node:s}));return i}(e,0),t}const $={},U=e=>{
|
||
console.error(e)},z=(e,...t)=>{console.log("WARN: "+e,...t)},K=(e,t)=>{
|
||
$[`${e}/${t}`]||(console.log(`Deprecated as of ${e}. ${t}`),$[`${e}/${t}`]=!0)
|
||
},G=s,V=a,W=Symbol("nomatch");return(e=>{
|
||
const n=Object.create(null),s=Object.create(null),a=[];let r=!0
|
||
;const l=/(^(<[^>]+>|\t|)+|\n)/gm,o="Could not find the language '{}', did you forget to load/include a language module?",g={
|
||
disableAutodetect:!0,name:"Plain text",contains:[]};let u={
|
||
noHighlightRe:/^(no-?highlight)$/i,
|
||
languageDetectRe:/\blang(?:uage)?-([\w-]+)\b/i,classPrefix:"hljs-",
|
||
tabReplace:null,useBR:!1,languages:null,__emitter:c};function h(e){
|
||
return u.noHighlightRe.test(e)}function d(e,t,n,i){let s="",a=""
|
||
;"object"==typeof t?(s=e,
|
||
n=t.ignoreIllegals,a=t.language,i=void 0):(K("10.7.0","highlight(lang, code, ...args) has been deprecated."),
|
||
K("10.7.0","Please use highlight(code, options) instead.\nhttps://github.com/highlightjs/highlight.js/issues/2277"),
|
||
a=e,s=t);const r={code:s,language:a};M("before:highlight",r)
|
||
;const l=r.result?r.result:f(r.language,r.code,n,i)
|
||
;return l.code=r.code,M("after:highlight",l),l}function f(e,t,s,l){
|
||
function c(e,t){const n=v.case_insensitive?t[0].toLowerCase():t[0]
|
||
;return Object.prototype.hasOwnProperty.call(e.keywords,n)&&e.keywords[n]}
|
||
function g(){null!=R.subLanguage?(()=>{if(""===M)return;let e=null
|
||
;if("string"==typeof R.subLanguage){
|
||
if(!n[R.subLanguage])return void k.addText(M)
|
||
;e=f(R.subLanguage,M,!0,_[R.subLanguage]),_[R.subLanguage]=e.top
|
||
}else e=p(M,R.subLanguage.length?R.subLanguage:null)
|
||
;R.relevance>0&&(O+=e.relevance),k.addSublanguage(e.emitter,e.language)
|
||
})():(()=>{if(!R.keywords)return void k.addText(M);let e=0
|
||
;R.keywordPatternRe.lastIndex=0;let t=R.keywordPatternRe.exec(M),n="";for(;t;){
|
||
n+=M.substring(e,t.index);const i=c(R,t);if(i){const[e,s]=i
|
||
;if(k.addText(n),n="",O+=s,e.startsWith("_"))n+=t[0];else{
|
||
const n=v.classNameAliases[e]||e;k.addKeyword(t[0],n)}}else n+=t[0]
|
||
;e=R.keywordPatternRe.lastIndex,t=R.keywordPatternRe.exec(M)}
|
||
n+=M.substr(e),k.addText(n)})(),M=""}function h(e){
|
||
return e.className&&k.openNode(v.classNameAliases[e.className]||e.className),
|
||
R=Object.create(e,{parent:{value:R}}),R}function d(e,t,n){let s=((e,t)=>{
|
||
const n=e&&e.exec(t);return n&&0===n.index})(e.endRe,n);if(s){if(e["on:end"]){
|
||
const n=new i(e);e["on:end"](t,n),n.isMatchIgnored&&(s=!1)}if(s){
|
||
for(;e.endsParent&&e.parent;)e=e.parent;return e}}
|
||
if(e.endsWithParent)return d(e.parent,t,n)}function m(e){
|
||
return 0===R.matcher.regexIndex?(M+=e[0],1):(I=!0,0)}function b(e){
|
||
const n=e[0],i=t.substr(e.index),s=d(R,e,i);if(!s)return W;const a=R
|
||
;a.skip?M+=n:(a.returnEnd||a.excludeEnd||(M+=n),g(),a.excludeEnd&&(M=n));do{
|
||
R.className&&k.closeNode(),R.skip||R.subLanguage||(O+=R.relevance),R=R.parent
|
||
}while(R!==s.parent)
|
||
;return s.starts&&(s.endSameAsBegin&&(s.starts.endRe=s.endRe),
|
||
h(s.starts)),a.returnEnd?0:n.length}let E={};function x(n,a){const l=a&&a[0]
|
||
;if(M+=n,null==l)return g(),0
|
||
;if("begin"===E.type&&"end"===a.type&&E.index===a.index&&""===l){
|
||
if(M+=t.slice(a.index,a.index+1),!r){const t=Error("0 width match regex")
|
||
;throw t.languageName=e,t.badRule=E.rule,t}return 1}
|
||
if(E=a,"begin"===a.type)return function(e){
|
||
const t=e[0],n=e.rule,s=new i(n),a=[n.__beforeBegin,n["on:begin"]]
|
||
;for(const n of a)if(n&&(n(e,s),s.isMatchIgnored))return m(t)
|
||
;return n&&n.endSameAsBegin&&(n.endRe=RegExp(t.replace(/[-/\\^$*+?.()|[\]{}]/g,"\\$&"),"m")),
|
||
n.skip?M+=t:(n.excludeBegin&&(M+=t),
|
||
g(),n.returnBegin||n.excludeBegin||(M=t)),h(n),n.returnBegin?0:t.length}(a)
|
||
;if("illegal"===a.type&&!s){
|
||
const e=Error('Illegal lexeme "'+l+'" for mode "'+(R.className||"<unnamed>")+'"')
|
||
;throw e.mode=R,e}if("end"===a.type){const e=b(a);if(e!==W)return e}
|
||
if("illegal"===a.type&&""===l)return 1
|
||
;if(L>1e5&&L>3*a.index)throw Error("potential infinite loop, way more iterations than matches")
|
||
;return M+=l,l.length}const v=N(e)
|
||
;if(!v)throw U(o.replace("{}",e)),Error('Unknown language: "'+e+'"')
|
||
;const w=T(v,{plugins:a});let y="",R=l||w;const _={},k=new u.__emitter(u);(()=>{
|
||
const e=[];for(let t=R;t!==v;t=t.parent)t.className&&e.unshift(t.className)
|
||
;e.forEach((e=>k.openNode(e)))})();let M="",O=0,A=0,L=0,I=!1;try{
|
||
for(R.matcher.considerAll();;){
|
||
L++,I?I=!1:R.matcher.considerAll(),R.matcher.lastIndex=A
|
||
;const e=R.matcher.exec(t);if(!e)break;const n=x(t.substring(A,e.index),e)
|
||
;A=e.index+n}return x(t.substr(A)),k.closeAllNodes(),k.finalize(),y=k.toHTML(),{
|
||
relevance:Math.floor(O),value:y,language:e,illegal:!1,emitter:k,top:R}}catch(n){
|
||
if(n.message&&n.message.includes("Illegal"))return{illegal:!0,illegalBy:{
|
||
msg:n.message,context:t.slice(A-100,A+100),mode:n.mode},sofar:y,relevance:0,
|
||
value:G(t),emitter:k};if(r)return{illegal:!1,relevance:0,value:G(t),emitter:k,
|
||
language:e,top:R,errorRaised:n};throw n}}function p(e,t){
|
||
t=t||u.languages||Object.keys(n);const i=(e=>{const t={relevance:0,
|
||
emitter:new u.__emitter(u),value:G(e),illegal:!1,top:g}
|
||
;return t.emitter.addText(e),t})(e),s=t.filter(N).filter(k).map((t=>f(t,e,!1)))
|
||
;s.unshift(i);const a=s.sort(((e,t)=>{
|
||
if(e.relevance!==t.relevance)return t.relevance-e.relevance
|
||
;if(e.language&&t.language){if(N(e.language).supersetOf===t.language)return 1
|
||
;if(N(t.language).supersetOf===e.language)return-1}return 0})),[r,l]=a,o=r
|
||
;return o.second_best=l,o}const m={"before:highlightElement":({el:e})=>{
|
||
u.useBR&&(e.innerHTML=e.innerHTML.replace(/\n/g,"").replace(/<br[ /]*>/g,"\n"))
|
||
},"after:highlightElement":({result:e})=>{
|
||
u.useBR&&(e.value=e.value.replace(/\n/g,"<br>"))}},b=/^(<[^>]+>|\t)+/gm,E={
|
||
"after:highlightElement":({result:e})=>{
|
||
u.tabReplace&&(e.value=e.value.replace(b,(e=>e.replace(/\t/g,u.tabReplace))))}}
|
||
;function x(e){let t=null;const n=(e=>{let t=e.className+" "
|
||
;t+=e.parentNode?e.parentNode.className:"";const n=u.languageDetectRe.exec(t)
|
||
;if(n){const t=N(n[1])
|
||
;return t||(z(o.replace("{}",n[1])),z("Falling back to no-highlight mode for this block.",e)),
|
||
t?n[1]:"no-highlight"}return t.split(/\s+/).find((e=>h(e)||N(e)))})(e)
|
||
;if(h(n))return;M("before:highlightElement",{el:e,language:n}),t=e
|
||
;const i=t.textContent,a=n?d(i,{language:n,ignoreIllegals:!0}):p(i)
|
||
;M("after:highlightElement",{el:e,result:a,text:i
|
||
}),e.innerHTML=a.value,((e,t,n)=>{const i=t?s[t]:n
|
||
;e.classList.add("hljs"),i&&e.classList.add(i)})(e,n,a.language),e.result={
|
||
language:a.language,re:a.relevance,relavance:a.relevance
|
||
},a.second_best&&(e.second_best={language:a.second_best.language,
|
||
re:a.second_best.relevance,relavance:a.second_best.relevance})}const v=()=>{
|
||
v.called||(v.called=!0,
|
||
K("10.6.0","initHighlighting() is deprecated. Use highlightAll() instead."),
|
||
document.querySelectorAll("pre code").forEach(x))};let w=!1;function y(){
|
||
"loading"!==document.readyState?document.querySelectorAll("pre code").forEach(x):w=!0
|
||
}function N(e){return e=(e||"").toLowerCase(),n[e]||n[s[e]]}
|
||
function R(e,{languageName:t}){"string"==typeof e&&(e=[e]),e.forEach((e=>{
|
||
s[e.toLowerCase()]=t}))}function k(e){const t=N(e)
|
||
;return t&&!t.disableAutodetect}function M(e,t){const n=e;a.forEach((e=>{
|
||
e[n]&&e[n](t)}))}
|
||
"undefined"!=typeof window&&window.addEventListener&&window.addEventListener("DOMContentLoaded",(()=>{
|
||
w&&y()}),!1),Object.assign(e,{highlight:d,highlightAuto:p,highlightAll:y,
|
||
fixMarkup:e=>{
|
||
return K("10.2.0","fixMarkup will be removed entirely in v11.0"),K("10.2.0","Please see https://github.com/highlightjs/highlight.js/issues/2534"),
|
||
t=e,
|
||
u.tabReplace||u.useBR?t.replace(l,(e=>"\n"===e?u.useBR?"<br>":e:u.tabReplace?e.replace(/\t/g,u.tabReplace):e)):t
|
||
;var t},highlightElement:x,
|
||
highlightBlock:e=>(K("10.7.0","highlightBlock will be removed entirely in v12.0"),
|
||
K("10.7.0","Please use highlightElement now."),x(e)),configure:e=>{
|
||
e.useBR&&(K("10.3.0","'useBR' will be removed entirely in v11.0"),
|
||
K("10.3.0","Please see https://github.com/highlightjs/highlight.js/issues/2559")),
|
||
u=V(u,e)},initHighlighting:v,initHighlightingOnLoad:()=>{
|
||
K("10.6.0","initHighlightingOnLoad() is deprecated. Use highlightAll() instead."),
|
||
w=!0},registerLanguage:(t,i)=>{let s=null;try{s=i(e)}catch(e){
|
||
if(U("Language definition for '{}' could not be registered.".replace("{}",t)),
|
||
!r)throw e;U(e),s=g}
|
||
s.name||(s.name=t),n[t]=s,s.rawDefinition=i.bind(null,e),s.aliases&&R(s.aliases,{
|
||
languageName:t})},unregisterLanguage:e=>{delete n[e]
|
||
;for(const t of Object.keys(s))s[t]===e&&delete s[t]},
|
||
listLanguages:()=>Object.keys(n),getLanguage:N,registerAliases:R,
|
||
requireLanguage:e=>{
|
||
K("10.4.0","requireLanguage will be removed entirely in v11."),
|
||
K("10.4.0","Please see https://github.com/highlightjs/highlight.js/pull/2844")
|
||
;const t=N(e);if(t)return t
|
||
;throw Error("The '{}' language is required, but not loaded.".replace("{}",e))},
|
||
autoDetection:k,inherit:V,addPlugin:e=>{(e=>{
|
||
e["before:highlightBlock"]&&!e["before:highlightElement"]&&(e["before:highlightElement"]=t=>{
|
||
e["before:highlightBlock"](Object.assign({block:t.el},t))
|
||
}),e["after:highlightBlock"]&&!e["after:highlightElement"]&&(e["after:highlightElement"]=t=>{
|
||
e["after:highlightBlock"](Object.assign({block:t.el},t))})})(e),a.push(e)},
|
||
vuePlugin:P(e).VuePlugin}),e.debugMode=()=>{r=!1},e.safeMode=()=>{r=!0
|
||
},e.versionString="10.7.2";for(const e in _)"object"==typeof _[e]&&t(_[e])
|
||
;return Object.assign(e,_),e.addPlugin(m),e.addPlugin(D),e.addPlugin(E),e})({})
|
||
}();"object"==typeof exports&&"undefined"!=typeof module&&(module.exports=hljs);hljs.registerLanguage("lua",(()=>{"use strict";return e=>{
|
||
const t="\\[=*\\[",a="\\]=*\\]",n={begin:t,end:a,contains:["self"]
|
||
},o=[e.COMMENT("--(?!\\[=*\\[)","$"),e.COMMENT("--\\[=*\\[",a,{contains:[n],
|
||
relevance:10})];return{name:"Lua",keywords:{$pattern:e.UNDERSCORE_IDENT_RE,
|
||
literal:"true false nil",
|
||
keyword:"and break do else elseif end for goto if in local not or repeat return then until while",
|
||
built_in:"_G _ENV _VERSION __index __newindex __mode __call __metatable __tostring __len __gc __add __sub __mul __div __mod __pow __concat __unm __eq __lt __le assert collectgarbage dofile error getfenv getmetatable ipairs load loadfile loadstring module next pairs pcall print rawequal rawget rawset require select setfenv setmetatable tonumber tostring type unpack xpcall arg self coroutine resume yield status wrap create running debug getupvalue debug sethook getmetatable gethook setmetatable setlocal traceback setfenv getinfo setupvalue getlocal getregistry getfenv io lines write close flush open output type read stderr stdin input stdout popen tmpfile math log max acos huge ldexp pi cos tanh pow deg tan cosh sinh random randomseed frexp ceil floor rad abs sqrt modf asin min mod fmod log10 atan2 exp sin atan os exit setlocale date getenv difftime remove time clock tmpname rename execute package preload loadlib loaded loaders cpath config path seeall string sub upper len gfind rep find match char dump gmatch reverse byte format gsub lower table setn insert getn foreachi maxn foreach concat sort remove"
|
||
},contains:o.concat([{className:"function",beginKeywords:"function",end:"\\)",
|
||
contains:[e.inherit(e.TITLE_MODE,{
|
||
begin:"([_a-zA-Z]\\w*\\.)*([_a-zA-Z]\\w*:)?[_a-zA-Z]\\w*"}),{className:"params",
|
||
begin:"\\(",endsWithParent:!0,contains:o}].concat(o)
|
||
},e.C_NUMBER_MODE,e.APOS_STRING_MODE,e.QUOTE_STRING_MODE,{className:"string",
|
||
begin:t,end:a,contains:[n],relevance:5}])}}})());hljs.registerLanguage("dos",(()=>{"use strict";return e=>{
|
||
const t=e.COMMENT(/^\s*@?rem\b/,/$/,{relevance:10});return{
|
||
name:"Batch file (DOS)",aliases:["bat","cmd"],case_insensitive:!0,
|
||
illegal:/\/\*/,keywords:{
|
||
keyword:"if else goto for in do call exit not exist errorlevel defined equ neq lss leq gtr geq",
|
||
built_in:"prn nul lpt3 lpt2 lpt1 con com4 com3 com2 com1 aux shift cd dir echo setlocal endlocal set pause copy append assoc at attrib break cacls cd chcp chdir chkdsk chkntfs cls cmd color comp compact convert date dir diskcomp diskcopy doskey erase fs find findstr format ftype graftabl help keyb label md mkdir mode more move path pause print popd pushd promt rd recover rem rename replace restore rmdir shift sort start subst time title tree type ver verify vol ping net ipconfig taskkill xcopy ren del"
|
||
},contains:[{className:"variable",begin:/%%[^ ]|%[^ ]+?%|![^ ]+?!/},{
|
||
className:"function",begin:"^\\s*[A-Za-z._?][A-Za-z0-9_$#@~.?]*(:|\\s+label)",
|
||
end:"goto:eof",contains:[e.inherit(e.TITLE_MODE,{
|
||
begin:"([_a-zA-Z]\\w*\\.)*([_a-zA-Z]\\w*:)?[_a-zA-Z]\\w*"}),t]},{
|
||
className:"number",begin:"\\b\\d+",relevance:0},t]}}})());hljs.registerLanguage("plaintext",(()=>{"use strict";return t=>({
|
||
name:"Plain text",aliases:["text","txt"],disableAutodetect:!0})})());
|
||
|
||
function go()
|
||
{
|
||
// Generate a table of contents from h* tags.
|
||
var toc = document.getElementById("toc");
|
||
toc.innerHTML = "";
|
||
var headings = document.querySelectorAll("h1");
|
||
for (var i = 0; i < headings.length; ++i)
|
||
{
|
||
var h = headings[i];
|
||
|
||
var anchor = document.createElement("a");
|
||
anchor.name = h.id;
|
||
h.parentNode.insertBefore(anchor, h);
|
||
|
||
var a = document.createElement("a");
|
||
a.href = "#" + h.id;
|
||
a.innerHTML = h.innerHTML;
|
||
|
||
var div = document.createElement("div");
|
||
div.appendChild(a);
|
||
div.className = h.tagName;
|
||
|
||
toc.appendChild(div);
|
||
}
|
||
|
||
// Apply syntax highlighting.
|
||
hljs.initHighlighting();
|
||
|
||
// Fix hyperlink styling inside highlighted comments.
|
||
var source_links = document.querySelectorAll("a > span");
|
||
for (var i = 0; i < source_links.length; ++i)
|
||
{
|
||
var e = source_links[i];
|
||
e.classList.replace("hljs-comment", "comment-web-link");
|
||
}
|
||
}
|
||
</script>
|
||
</head>
|
||
|
||
<!-- ----------------------------------------------------- -->
|
||
<body onload="go();">
|
||
<table width="100%" style="border:none"><tr>
|
||
<td style="text-align:left">
|
||
<div id="toc"></div>
|
||
</td>
|
||
<td style="text-align:right">
|
||
<div id="header">
|
||
<div id="title">Clink v1.2.9</div>
|
||
<div id="url">
|
||
<a href="https://github.com/chrisant996/clink">
|
||
https://github.com/chrisant996/clink
|
||
</a>
|
||
</div>
|
||
<div id="author">
|
||
<a href="mailto:sparrowhawk996@gmail.com">Christopher Antos</a> (renovater)
|
||
</div>
|
||
<div id="author">
|
||
<a href="https://twitter.com/choddlander">Martin Ridgers</a> (creator)
|
||
</div>
|
||
</div>
|
||
</td>
|
||
</tr></table>
|
||
<div id="content">
|
||
<div class="section" id="documentation">
|
||
<h1 id="what-is-clink">What is Clink?</h1>
|
||
<p>Clink combines the native Windows shell cmd.exe with the powerful command line editing features of the GNU Readline library, which provides rich completion, history, and line-editing capabilities. Readline is best known for its use in the well-known Unix shell Bash, the standard shell for Mac OS X and many Linux distributions.</p>
|
||
<h1 id="features">Features</h1>
|
||
<ul>
|
||
<li>The same line editing as Bash (from the <a href="https://tiswww.case.edu/php/chet/readline/rltop.html">GNU Readline library</a> version 8.1).</li>
|
||
<li>History persistence between sessions.</li>
|
||
<li>Context sensitive completion;<ul>
|
||
<li>Executables (and aliases).</li>
|
||
<li>Directory commands.</li>
|
||
<li>Environment variables.</li>
|
||
</ul>
|
||
</li>
|
||
<li>Context sensitive colored input text.</li>
|
||
<li>New keyboard shortcuts;<ul>
|
||
<li>Paste from clipboard (<kbd>Ctrl</kbd>+<kbd>V</kbd>).</li>
|
||
<li>Incremental history search (<kbd>Ctrl</kbd>+<kbd>R</kbd> and <kbd>Ctrl</kbd>+<kbd>S</kbd>).</li>
|
||
<li>Powerful completion (<kbd>Tab</kbd>).</li>
|
||
<li>Undo (<kbd>Ctrl</kbd>+<kbd>Z</kbd>).</li>
|
||
<li>Automatic <code>cd ..</code> (<kbd>Ctrl</kbd>+<kbd>Alt</kbd>+<kbd>U</kbd>).</li>
|
||
<li>Environment variable expansion (<kbd>Ctrl</kbd>+<kbd>Alt</kbd>+<kbd>E</kbd>).</li>
|
||
<li>Doskey alias expansion (<kbd>Ctrl</kbd>+<kbd>Alt</kbd>+<kbd>F</kbd>).</li>
|
||
<li>Scroll the screen buffer (<kbd>Alt</kbd>+<kbd>Up</kbd>, etc).</li>
|
||
<li><kbd>Shift</kbd>+Arrow keys to select text, typing replaces selected text, etc.</li>
|
||
<li>(press <kbd>Alt</kbd>+<kbd>H</kbd> for many more...)</li>
|
||
</ul>
|
||
</li>
|
||
<li>Directory shortcuts;<ul>
|
||
<li>Typing a directory name followed by a path separator is a shortcut for <code>cd /d</code> to that directory.</li>
|
||
<li>Typing <code>..</code> or <code>...</code> is a shortcut for <code>cd ..</code> or <code>cd ..\..</code> (each additional <code>.</code> adds another <code>\..</code>).</li>
|
||
<li>Typing <code>-</code> or <code>cd -</code> changes to the previous current working directory.</li>
|
||
</ul>
|
||
</li>
|
||
<li>Scriptable completion with Lua.</li>
|
||
<li>Scriptable key bindings with Lua.</li>
|
||
<li>Colored and scriptable prompt.</li>
|
||
<li>Auto-answering of the "Terminate batch job?" prompt.</li>
|
||
</ul>
|
||
<p>By default Clink binds <kbd>Alt</kbd>+<kbd>H</kbd> to display the current key bindings. More features can also be found in GNU's <a href="https://tiswww.cwru.edu/php/chet/readline/readline.html">Readline</a> and <a href="https://tiswww.cwru.edu/php/chet/readline/history.html">History</a> libraries' manuals.</p>
|
||
<blockquote>
|
||
<p>
|
||
<strong>Want some quick but powerful tips to get started?</strong>
|
||
</p>
|
||
<p>
|
||
<table>
|
||
<tr><td><kbd>Ctrl</kbd>+<kbd>O</kbd></td><td>This is <code>operate-and-get-next</code>, which accepts the current input line and gets the next history line. You can search history for a command, then press <kbd>Ctrl</kbd>+<kbd>O</kbd> to run that command and queue up the next command after it. Repeat it to conveniently rerun a series of commands from the history.</td></tr>
|
||
<tr><td><kbd>Alt</kbd>+<kbd>.</kbd></td><td>This is <code>yank-last-arg</code>, which inserts the last argument from the previous line. You can use it repeatedly to cycle backwards through the history, inserting the last argument from each line. Learn more by reading up on the "yank" features in the Readline manual.</td></tr>
|
||
<tr><td><kbd>Ctrl</kbd>+<kbd>R</kbd></td><td>This is <code>reverse-search-history</code>, which incrementally searches the history. Press it, then type, and it does a reverse incremental search while you type. Press <kbd>Ctrl</kbd>+<kbd>R</kbd> again (and again, etc) to search for other matches of the search text. Learn more by reading up on the "search" and "history" features in the Readline manual.</td></tr>
|
||
<tr><td><kbd>Ctrl</kbd>+<kbd>Alt</kbd>+<kbd>D</kbd></td><td>This is <code>remove-history</code>, which deletes the currently selected history line after using any of the history search or navigation commands.</td></tr>
|
||
<tr><td><kbd>Ctrl</kbd>+<kbd>Alt</kbd>+<kbd>K</kbd></td><td>This is <code>add-history</code>, which adds the current line to the history without executing it, and then clears the input line.</td></tr>
|
||
<tr><td><kbd>Ctrl</kbd>+<kbd>Alt</kbd>+<kbd>N</kbd></td><td>This is <code>clink-menu-complete-numbers</code>, which grabs numbers with 3 or more digits from the current console screen and cycles through inserting them as completions (binary, octal, decimal, hexadecimal). Super handy for quickly inserting a commit hash that was printed as output from a preceding command.</td></tr>
|
||
<tr><td><kbd>Alt</kbd>+<kbd>0</kbd> to <kbd>Alt</kbd>+<kbd>9</kbd></td><td>These are <code>digit-argument</code>, which let you enter a numeric value used by many commands. For example <kbd>Ctrl</kbd>+<kbd>Alt</kbd>+<kbd>W</kbd> copies the current word to the clipboard, but if you first type <kbd>Alt</kbd>+<kbd>2</kbd> followed by <kbd>Ctrl</kbd>+<kbd>Alt</kbd>+<kbd>W</kbd> then it copies the 3rd word to the clipboard (the first word is 0, the second is 1, etc). Learn more by reading up on "Readline Arguments" in the Readline manual.</td></tr>
|
||
<tr><td><kbd>Alt</kbd>+<kbd>H</kbd></td><td>This is <code>clink-show-help</code>, which lists the key bindings and commands. Learn more by visiting <a href="#keybindings">Key Bindings</a>.</td></tr>
|
||
</table>
|
||
</p>
|
||
</blockquote>
|
||
|
||
<h1 id="usage">Usage</h1>
|
||
<p>There are several ways to start Clink.</p>
|
||
<ol>
|
||
<li>If you installed the auto-run, just start <code>cmd.exe</code>. Run <code>clink autorun --help</code> for more info.</li>
|
||
<li>To manually start, run the Clink shortcut from the Start menu (or the clink.bat located in the install directory).</li>
|
||
<li>To establish Clink to an existing <code>cmd.exe</code> process, use <code><install_dir>\clink.exe inject</code>.</li>
|
||
</ol>
|
||
<h1 id="upgrading-from-clink-v049">Upgrading from Clink v0.4.9</h1>
|
||
<p>The new Clink tries to be as backward compatible with Clink v0.4.9 as possible. However, in some cases upgrading may require a little bit of configuration work.</p>
|
||
<ul>
|
||
<li>Some key binding sequences have changed; see <a href="#keybindings">Key Bindings</a> for more information.</li>
|
||
<li>Match coloring is now done by Readline and is configured differently; see <a href="#completioncolors">Completion Colors</a> for more information.</li>
|
||
<li>Settings and history should migrate automatically if the new <code>clink_settings</code> and <code>clink_history</code> files don't exist (deleting them will cause migration to happen again). To find the directory that contains these files, run <code>clink info</code> and look for the "state" line.</li>
|
||
<li>Script compatibility should be very good, but some scripts may still encounter problems. If you do encounter a compatibility problem you can look for an updated version of the script, update the script yourself, or visit the <a href="https://github.com/chrisant996/clink/issues">repo</a> and open an issue describing details about the compatibility problem.</li>
|
||
<li>Some settings have changed slightly, and there are many new settings. See <a href="#configclink">Configuring Clink</a> for more information.</li>
|
||
</ul>
|
||
<h1 id="how-clink-works">How Clink Works</h1>
|
||
<p>When running Clink via the methods above, Clink checks the parent process is supported and injects a DLL into it. The DLL then hooks the WriteConsole() and ReadConsole() Windows functions. The former is so that Clink can capture the current prompt, and the latter hook allows Clink to provide its own Readline-powered command line editing.</p>
|
||
<a name="privacy"/>
|
||
|
||
<h2 id="privacy">Privacy</h2>
|
||
<p>Clink does not collect user data. Clink writes diagnostic information to its local log file, and does not transmit the log file off the local computer. For the location of the log file, refer to <a href="#filelocations">File Locations</a> or run <code>clink info</code>.</p>
|
||
<a name="configclink"/>
|
||
|
||
<h1 id="configuring-clink">Configuring Clink</h1>
|
||
<p>The easiest way to configure Clink is to use Clink's <code>set</code> command line option. This can list, query, and set Clink's settings. Run <code>clink set --help</code> from a Clink-installed cmd.exe process to learn more both about how to use it and to get descriptions for Clink's various options.</p>
|
||
<p>The following table describes the available Clink settings:</p>
|
||
<table>
|
||
<thead>
|
||
<tr>
|
||
<th align="center">Name</th>
|
||
<th align="center">Default</th>
|
||
<th>Description</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody><tr>
|
||
<td align="center"><code>clink.colorize_input</code></td>
|
||
<td align="center">True</td>
|
||
<td>Enables context sensitive coloring for the input text (see <a href="#classifywords">Coloring The Input Text</a>).</td>
|
||
</tr>
|
||
<tr>
|
||
<td align="center"><code>clink.paste_crlf</code></td>
|
||
<td align="center"><code>crlf</code></td>
|
||
<td>What to do with CR and LF characters on paste. Setting this to <code>delete</code> deletes them, <code>space</code> replaces them with spaces, <code>ampersand</code> replaces them with ampersands, and <code>crlf</code> pastes them as-is (executing commands that end with a newline).</td>
|
||
</tr>
|
||
<tr>
|
||
<td align="center"><code>clink.path</code></td>
|
||
<td align="center"></td>
|
||
<td>A list of paths to load Lua scripts. Multiple paths can be delimited semicolons.</td>
|
||
</tr>
|
||
<tr>
|
||
<td align="center"><code>clink.promptfilter</code></td>
|
||
<td align="center">True</td>
|
||
<td>Enable prompt filtering by Lua scripts.</td>
|
||
</tr>
|
||
<tr>
|
||
<td align="center"><code>cmd.auto_answer</code></td>
|
||
<td align="center"><code>off</code></td>
|
||
<td>Automatically answers cmd.exe's "Terminate batch job (Y/N)?" prompts. <code>off</code> = disabled, <code>answer_yes</code> = answer Y, <code>answer_no</code> = answer N.</td>
|
||
</tr>
|
||
<tr>
|
||
<td align="center"><code>cmd.ctrld_exits</code></td>
|
||
<td align="center">True</td>
|
||
<td><kbd>Ctrl</kbd>+<kbd>D</kbd> exits the process when it is pressed on an empty line.</td>
|
||
</tr>
|
||
<tr>
|
||
<td align="center"><code>color.arg</code></td>
|
||
<td align="center"></td>
|
||
<td>The color for arguments in the input line when <code>clink.colorize_input</code> is enabled.</td>
|
||
</tr>
|
||
<tr>
|
||
<td align="center"><code>color.argmatcher</code></td>
|
||
<td align="center"></td>
|
||
<td>The color for the command name in the input line when <code>clink.colorize_input</code> is enabled, if the command name has an argmatcher available.</td>
|
||
</tr>
|
||
<tr>
|
||
<td align="center"><a name="color_cmd"/><code>color.cmd</code></td>
|
||
<td align="center"><code>bold</code></td>
|
||
<td>Used when Clink displays shell (CMD.EXE) command completions, and in the input line when <code>clink.colorize_input</code> is enabled.</td>
|
||
</tr>
|
||
<tr>
|
||
<td align="center"><a name="color_doskey"/><code>color.doskey</code></td>
|
||
<td align="center"><code>bright cyan</code></td>
|
||
<td>Used when Clink displays doskey alias completions, and in the input line when <code>clink.colorize_input</code> is enabled.</td>
|
||
</tr>
|
||
<tr>
|
||
<td align="center"><code>color.filtered</code></td>
|
||
<td align="center"><code>bold</code></td>
|
||
<td>The default color for filtered completions (see <a href="#filteringthematchdisplay">Filtering the Match Display</a>).</td>
|
||
</tr>
|
||
<tr>
|
||
<td align="center"><code>color.flag</code></td>
|
||
<td align="center"><code>default</code></td>
|
||
<td>The color for flags in the input line when <code>clink.colorize_input</code> is enabled.</td>
|
||
</tr>
|
||
<tr>
|
||
<td align="center"><a name="color_hidden"/><code>color.hidden</code></td>
|
||
<td align="center"></td>
|
||
<td>Used when Clink displays file completions with the "hidden" attribute.</td>
|
||
</tr>
|
||
<tr>
|
||
<td align="center"><code>color.horizscroll</code></td>
|
||
<td align="center"></td>
|
||
<td>Used when Clink displays the <code><</code> or <code>></code> horizontal scroll indicators when Readline's <code>horizontal-scroll-mode</code> variable is set.</td>
|
||
</tr>
|
||
<tr>
|
||
<td align="center"><code>color.input</code></td>
|
||
<td align="center"></td>
|
||
<td>Used when Clink displays the input line text. Note that when <code>clink.colorize_input</code> is disabled, the entire input line is displayed using <code>color.input</code>.</td>
|
||
</tr>
|
||
<tr>
|
||
<td align="center"><code>color.interact</code></td>
|
||
<td align="center"><code>bold</code></td>
|
||
<td>Used when Clink displays text or prompts such as a pager's <code>--More?--</code> prompt.</td>
|
||
</tr>
|
||
<tr>
|
||
<td align="center"><code>color.message</code></td>
|
||
<td align="center"><code>default</code></td>
|
||
<td>The color for the message area (e.g. the search prompt message, digit argument prompt message, etc).</td>
|
||
</tr>
|
||
<tr>
|
||
<td align="center"><code>color.modmark</code></td>
|
||
<td align="center"></td>
|
||
<td>Used when Clink displays the <code>*</code> mark on modified history lines when Readline's <code>mark-modified-lines</code> variable and Clink's <code>color.input</code> setting are both set. Falls back to <code>color.input</code> if not set.</td>
|
||
</tr>
|
||
<tr>
|
||
<td align="center"><code>color.prompt</code></td>
|
||
<td align="center"></td>
|
||
<td>When set, this is used as the default color for the prompt. But it's overridden by any colors set by <a href="#customisingtheprompt">Customising The Prompt</a>.</td>
|
||
</tr>
|
||
<tr>
|
||
<td align="center"><a name="color_readonly"/><code>color.readonly</code></td>
|
||
<td align="center"></td>
|
||
<td>Used when Clink displays file completions with the "readonly" attribute.</td>
|
||
</tr>
|
||
<tr>
|
||
<td align="center"><code>color.selection</code></td>
|
||
<td align="center"></td>
|
||
<td>The color for selected text in the input line. If no color is set, then reverse video is used.</td>
|
||
</tr>
|
||
<tr>
|
||
<td align="center"><code>color.unexpected</code></td>
|
||
<td align="center"><code>default</code></td>
|
||
<td>The color for unexpected arguments in the input line when <code>clink.colorize_input</code> is enabled.</td>
|
||
</tr>
|
||
<tr>
|
||
<td align="center"><code>debug.log_terminal</code></td>
|
||
<td align="center">False</td>
|
||
<td>Logs all terminal input and output to the clink.log file. This is intended for diagnostic purposes only, and can make the log file grow significantly.</td>
|
||
</tr>
|
||
<tr>
|
||
<td align="center"><code>doskey.enhanced</code></td>
|
||
<td align="center">True</td>
|
||
<td>Enhanced Doskey adds the expansion of macros that follow <code>|</code> and <code>&</code> command separators and respects quotes around words when parsing <code>$1</code>..<code>$9</code> tags. Note that these features do not apply to Doskey use in Batch files.</td>
|
||
</tr>
|
||
<tr>
|
||
<td align="center"><code>exec.cwd</code></td>
|
||
<td align="center">True</td>
|
||
<td>When matching executables as the first word (<code>exec.enable</code>), include executables in the current directory. (This is implicit if the word being completed is a relative path).</td>
|
||
</tr>
|
||
<tr>
|
||
<td align="center"><code>exec.dirs</code></td>
|
||
<td align="center">True</td>
|
||
<td>When matching executables as the first word (<code>exec.enable</code>), also include directories relative to the current working directory as matches.</td>
|
||
</tr>
|
||
<tr>
|
||
<td align="center"><code>exec.enable</code></td>
|
||
<td align="center">True</td>
|
||
<td>Match executables when completing the first word of a line.</td>
|
||
</tr>
|
||
<tr>
|
||
<td align="center"><code>exec.path</code></td>
|
||
<td align="center">True</td>
|
||
<td>When matching executables as the first word (<code>exec.enable</code>), include executables found in the directories specified in the <code>%PATH%</code> environment variable.</td>
|
||
</tr>
|
||
<tr>
|
||
<td align="center"><code>exec.space_prefix</code></td>
|
||
<td align="center">True</td>
|
||
<td>If the line begins with whitespace then Clink bypasses executable matching (<code>exec.path</code>) and will do normal files matching instead.</td>
|
||
</tr>
|
||
<tr>
|
||
<td align="center"><code>files.hidden</code></td>
|
||
<td align="center">True</td>
|
||
<td>Includes or excludes files with the "hidden" attribute set when generating file lists.</td>
|
||
</tr>
|
||
<tr>
|
||
<td align="center"><code>files.system</code></td>
|
||
<td align="center">False</td>
|
||
<td>Includes or excludes files with the "system" attribute set when generating file lists.</td>
|
||
</tr>
|
||
<tr>
|
||
<td align="center"><code>history.dont_add_to_history_cmds</code></td>
|
||
<td align="center"><code>exit history</code></td>
|
||
<td>List of commands that aren't automatically added to the history. Commands are separated by spaces, commas, or semicolons. Default is <code>exit history</code>, to exclude both of those commands.</td>
|
||
</tr>
|
||
<tr>
|
||
<td align="center"><code>history.dupe_mode</code></td>
|
||
<td align="center"><code>erase_prev</code></td>
|
||
<td>If a line is a duplicate of an existing history entry Clink will erase the duplicate when this is set to 'erase_prev'. Setting it to 'ignore' will not add duplicates to the history, and setting it to 'add' will always add lines (except when overridden by <code>history.sticky_search</code>).</td>
|
||
</tr>
|
||
<tr>
|
||
<td align="center"><code>history.expand_mode</code></td>
|
||
<td align="center"><code>not_quoted</code></td>
|
||
<td>The <code>!</code> character in an entered line can be interpreted to introduce words from the history. This can be enabled and disable by setting this value to <code>on</code> or <code>off</code>. Values of <code>not_squoted</code>, <code>not_dquoted</code>, or <code>not_quoted</code> will skip any <code>!</code> character quoted in single, double, or both quotes respectively.</td>
|
||
</tr>
|
||
<tr>
|
||
<td align="center"><code>history.ignore_space</code></td>
|
||
<td align="center">True</td>
|
||
<td>Ignore lines that begin with whitespace when adding lines in to the history.</td>
|
||
</tr>
|
||
<tr>
|
||
<td align="center"><code>history.max_lines</code></td>
|
||
<td align="center">2500</td>
|
||
<td>The number of history lines to save if <code>history.save</code> is enabled (1 to 50000).</td>
|
||
</tr>
|
||
<tr>
|
||
<td align="center"><code>history.save</code></td>
|
||
<td align="center">True</td>
|
||
<td>Saves history between sessions. When disabled, history is neither read from nor written to a master history list; history for each session exists only in memory until the session ends.</td>
|
||
</tr>
|
||
<tr>
|
||
<td align="center"><code>history.shared</code></td>
|
||
<td align="center">False</td>
|
||
<td>When history is shared, all instances of Clink update the master history list after each command and reload the master history list on each prompt. When history is not shared, each instance updates the master history list on exit.</td>
|
||
</tr>
|
||
<tr>
|
||
<td align="center"><code>history.sticky_search</code></td>
|
||
<td align="center">False</td>
|
||
<td>When enabled, reusing a history line does not add the reused line to the end of the history, and it leaves the history search position on the reused line so next/prev history can continue from there (e.g. replaying commands via <kbd>Up</kbd> several times then <kbd>Enter</kbd>, <kbd>Down</kbd>, <kbd>Enter</kbd>, etc).</td>
|
||
</tr>
|
||
<tr>
|
||
<td align="center"><code>lua.break_on_error</code></td>
|
||
<td align="center">False</td>
|
||
<td>Breaks into Lua debugger on Lua errors.</td>
|
||
</tr>
|
||
<tr>
|
||
<td align="center"><code>lua.break_on_traceback</code></td>
|
||
<td align="center">False</td>
|
||
<td>Breaks into Lua debugger on <code>traceback()</code>.</td>
|
||
</tr>
|
||
<tr>
|
||
<td align="center"><code>lua.debug</code></td>
|
||
<td align="center">False</td>
|
||
<td>Loads a simple embedded command line debugger when enabled. Breakpoints can be added by calling <code>pause()</code>.</td>
|
||
</tr>
|
||
<tr>
|
||
<td align="center"><code>lua.path</code></td>
|
||
<td align="center"></td>
|
||
<td>Value to append to <code>package.path</code>. Used to search for Lua scripts specified in <code>require()</code> statements.</td>
|
||
</tr>
|
||
<tr>
|
||
<td align="center"><a name="lua_reload_scripts"/><code>lua.reload_scripts</code></td>
|
||
<td align="center">False</td>
|
||
<td>When false, Lua scripts are loaded once and are only reloaded if forced (see <a href="#lua-scripts-location">The Location of Lua Scripts</a> for details). When true, Lua scripts are loaded each time the edit prompt is activated.</td>
|
||
</tr>
|
||
<tr>
|
||
<td align="center"><code>lua.strict</code></td>
|
||
<td align="center">True</td>
|
||
<td>When enabled, argument errors cause Lua scripts to fail. This may expose bugs in some older scripts, causing them to fail where they used to succeed. In that case you can try turning this off, but please alert the script owner about the issue so they can fix the script.</td>
|
||
</tr>
|
||
<tr>
|
||
<td align="center"><code>lua.traceback_on_error</code></td>
|
||
<td align="center">False</td>
|
||
<td>Prints stack trace on Lua errors.</td>
|
||
</tr>
|
||
<tr>
|
||
<td align="center"><code>match.ignore_accent</code></td>
|
||
<td align="center">True</td>
|
||
<td>Controls accent sensitivity when completing matches. For example, <code>ä</code> and <code>a</code> are considered equivalent with this enabled.</td>
|
||
</tr>
|
||
<tr>
|
||
<td align="center"><code>match.ignore_case</code></td>
|
||
<td align="center"><code>relaxed</code></td>
|
||
<td>Controls case sensitivity when completing matches. <code>off</code> = case sensitive, <code>on</code> = case insensitive, <code>relaxed</code> = case insensitive plus <code>-</code> and <code>_</code> are considered equal.</td>
|
||
</tr>
|
||
<tr>
|
||
<td align="center"><code>match.sort_dirs</code></td>
|
||
<td align="center"><code>with</code></td>
|
||
<td>How to sort matching directory names. <code>before</code> = before files, <code>with</code> = with files, <code>after</code> = after files.</td>
|
||
</tr>
|
||
<tr>
|
||
<td align="center"><code>match.translate_slashes</code></td>
|
||
<td align="center"><code>system</code></td>
|
||
<td>File and directory completions can be translated to use consistent slashes. The default is <code>system</code> to use the appropriate path separator for the OS host (backslashes on Windows). Use <code>slash</code> to use forward slashes, or <code>backslash</code> to use backslashes. Use <code>off</code> to turn off translating slashes from custom match generators.</td>
|
||
</tr>
|
||
<tr>
|
||
<td align="center"><code>match.wild</code></td>
|
||
<td align="center">True</td>
|
||
<td>Matches <code>?</code> and <code>*</code> wildcards when using any of the <code>menu-complete</code> commands or the <code>clink-popup-complete</code> command. Turn this off to behave how bash does, and not match wildcards.</td>
|
||
</tr>
|
||
<tr>
|
||
<td align="center"><code>readline.hide_stderr</code></td>
|
||
<td align="center">False</td>
|
||
<td>Suppresses stderr from the Readline library. Enable this if Readline error messages are getting in the way.</td>
|
||
</tr>
|
||
<tr>
|
||
<td align="center"><code>terminal.adjust_cursor_style</code></td>
|
||
<td align="center">True</td>
|
||
<td>When enabled, Clink adjusts the cursor shape and visibility to show Insert Mode, produce the visible bell effect, avoid disorienting cursor flicker, and to support ANSI escape codes that adjust the cursor shape and visibility. But it interferes with the Windows 10 Cursor Shape console setting. You can make the Cursor Shape setting work by disabling this Clink setting (and the features this provides).</td>
|
||
</tr>
|
||
<tr>
|
||
<td align="center"><code>terminal.differentiate_keys</code></td>
|
||
<td align="center">False</td>
|
||
<td>When enabled, pressing <kbd>Ctrl</kbd> + <kbd>H</kbd> or <kbd>I</kbd> or <kbd>M</kbd> or <kbd>[</kbd> generate special key sequences to enable binding them separately from <kbd>Backspace</kbd> or <kbd>Tab</kbd> or <kbd>Enter</kbd> or <kbd>Esc</kbd>.</td>
|
||
</tr>
|
||
<tr>
|
||
<td align="center"><code>terminal.emulation</code></td>
|
||
<td align="center"><code>auto</code></td>
|
||
<td>Clink can either emulate a virtual terminal and handle ANSI escape codes itself, or let the console host natively handle ANSI escape codes. <code>native</code> = pass output directly to the console host process, <code>emulate</code> = clink handles ANSI escape codes itself, <code>auto</code> = emulate except when running in ConEmu, Windows Terminal, or Windows 10 new console.</td>
|
||
</tr>
|
||
<tr>
|
||
<td align="center"><code>terminal.use_altgr_substitute</code></td>
|
||
<td align="center">False</td>
|
||
<td>Support Windows' <kbd>Ctrl</kbd>-<kbd>Alt</kbd> substitute for <kbd>AltGr</kbd>. Turning this off may resolve collisions with Readline's key bindings.</td>
|
||
</tr>
|
||
</tbody></table>
|
||
<p/>
|
||
|
||
<blockquote>
|
||
<p><strong>Compatibility Notes:</strong></p>
|
||
<ul>
|
||
<li>The <code>esc_clears_line</code> setting has been replaced by a <code>clink-reset-line</code> command that is by default bound to the <kbd>Escape</kbd> key. See <a href="#keybindings">Key Bindings</a> and <a href="https://tiswww.cwru.edu/php/chet/readline/readline.html">Readline</a> for more information.</li>
|
||
<li>The <code>match_colour</code> setting has been removed, and Clink now supports Readline's completion coloring. See <a href="#completioncolors">Completion Colors</a> for more information.</li>
|
||
</ul>
|
||
</blockquote>
|
||
<a name="colorsettings"/>
|
||
|
||
<h2 id="color-settings">Color Settings</h2>
|
||
<h3 id="friendly-color-names">Friendly Color Names</h3>
|
||
<p>The Clink color settings use the following syntax:</p>
|
||
<p><code>[<span class="arg">attributes</span>] [<span class="arg">foreground_color</span>] [on [<span class="arg">background_color</span>]]</code></p>
|
||
<p>Optional attributes (can be abbreviated to 3 letters):</p>
|
||
<ul>
|
||
<li><code>bold</code> or <code>nobold</code> adds or removes boldface (usually represented by forcing the color to use high intensity if it doesn't already).</li>
|
||
<li><code>underline</code> or <code>nounderline</code> adds or removes an underline.</li>
|
||
</ul>
|
||
<p>Optional colors for <span class="arg">foreground_color</span> and <span class="arg">background_color</span> (can be abbreviated to 3 letters):</p>
|
||
<ul>
|
||
<li><code>default</code> or <code>normal</code> uses the default color as defined by the current color theme in the console window.</li>
|
||
<li><code>black</code>, <code>red</code>, <code>green</code>, <code>yellow</code>, <code>blue</code>, <code>cyan</code>, <code>magenta</code>, <code>white</code> are the basic colors names.</li>
|
||
<li><code>bright</code> can be combined with any of the other color names to make them bright (high intensity).</li>
|
||
</ul>
|
||
<p>Examples (specific results may depend on the console host program):</p>
|
||
<ul>
|
||
<li><code>bri yel</code> for bright yellow foreground on default background color.</li>
|
||
<li><code>bold</code> for bright default foreground on default background color.</li>
|
||
<li><code>underline bright black on white</code> for dark gray (bright black) foreground on light gray (white) background.</li>
|
||
<li><code>default on blue</code> for default foreground color on blue background.</li>
|
||
</ul>
|
||
<h3 id="alternative-sgr-syntax">Alternative SGR Syntax</h3>
|
||
<p>It's also possible to set any ANSI <a href="https://en.wikipedia.org/wiki/ANSI_escape_code#SGR">SGR escape code</a> using <code>sgr <span class="arg">SGR_parameters</span></code> (for example <code>sgr 7</code> is the code for reverse video, which swaps the foreground and background colors).</p>
|
||
<p>Be careful, since some escape code sequences might behave strangely.</p>
|
||
<a name="filelocations"/>
|
||
|
||
<h2 id="file-locations">File Locations</h2>
|
||
<p>Settings and history are persisted to disk from session to session. The location of these files depends on which distribution of Clink was used. If you installed Clink using the .exe installer then Clink uses the current user's non-roaming application data directory. This user directory is usually found in one of the following locations;</p>
|
||
<ul>
|
||
<li>Windows XP: <code>c:\Documents and Settings\<username>\Local Settings\Application Data\clink</code></li>
|
||
<li>Windows Vista onwards: <code>c:\Users\<username>\AppData\Local\clink</code></li>
|
||
</ul>
|
||
<p>All of the above locations can be overridden using the <code>--profile <span class="arg">path</span></code> command line option which is specified when injecting Clink into cmd.exe using <code>clink inject</code>. Or with the <code>%CLINK_PROFILE%</code> environment variable if it is already present when Clink is injected (this envvar takes precedence over any other mechanism of specifying a profile directory, if more than one was used).</p>
|
||
<p>You can use <code>clink info</code> to find the directories and configuration files for the current Clink session.</p>
|
||
<h2 id="command-line-options">Command Line Options</h2>
|
||
<p>
|
||
<dt>clink</dt>
|
||
<dd>
|
||
Shows command line usage help.</dd>
|
||
</p>
|
||
|
||
<p>
|
||
<dt>clink inject</dt>
|
||
<dd>
|
||
Injects Clink into a CMD.EXE process.<br/>
|
||
See <code>clink inject --help</code> for more information.</dd>
|
||
</p>
|
||
|
||
<p>
|
||
<dt>clink autorun</dt>
|
||
<dd>
|
||
Manages Clink's entry in CMD.EXE's autorun section, which can automatically inject Clink when starting CMD.EXE.<br/>
|
||
When Clink is installed for autorun, the automatic inject can be overridden by setting the <code>CLINK_NOAUTORUN</code> environment variable (to any value).<br/>
|
||
See <code>clink autorun --help</code> for more information.</dd>
|
||
</p>
|
||
|
||
<p>
|
||
<dt>clink set</dt>
|
||
<dd>
|
||
<code>clink set</code> by itself lists all settings and their values.<br/>
|
||
<code>clink set <span class="arg">setting_name</span></code> describes the setting shows its current value.<br/>
|
||
<code>clink set <span class="arg">setting_name</span> clear</code> resets the setting to its default value.<br/>
|
||
<code>clink set <span class="arg">setting_name</span> <span class="arg">value</span></code> sets the setting to the specified value.</dd>
|
||
</p>
|
||
|
||
<p>
|
||
<dt>clink installscripts</dt>
|
||
<dd>
|
||
Adds a path to search for Lua scripts.<br/>
|
||
The path is stored in the registry and applies to all installations of Clink, regardless where their config paths are, etc. This is intended to make it easy for package managers like Scoop to be able to install (and uninstall) scripts for use with Clink.</br>
|
||
See <code>clink installscripts --help</code> for more information.</dd>
|
||
</p>
|
||
|
||
<p>
|
||
<dt>clink uninstallscripts</dt>
|
||
<dd>
|
||
Removes a path added by `clink installscripts`.</br>
|
||
See <code>clink uninstallscripts --help</code> for more information.</dd>
|
||
</p>
|
||
|
||
<p>
|
||
<dt>clink history</dt>
|
||
<dd>
|
||
Lists the command history.<br/>
|
||
See <code>clink history --help</code> for more information.<br/>
|
||
Also, Clink automatically defines <code>history</code> as an alias for <code>clink history</code>.</dd>
|
||
</p>
|
||
|
||
<p>
|
||
<dt>clink info</dt>
|
||
<dd>
|
||
Prints information about Clink, including the version and various configuration directories and files.<br/>
|
||
Or <code>clink --version</code> shows just the version number.</dd>
|
||
</p>
|
||
|
||
<p>
|
||
<dt>clink echo</dt>
|
||
<dd>
|
||
Echos key sequences to use in the .inputrc files for binding keys to Clink commands. Each key pressed prints the associated key sequence on a separate line, until <kbd>Ctrl</kbd>+<kbd>C</kbd> is pressed.</dd>
|
||
</p>
|
||
|
||
<h2 id="portable-configuration">Portable Configuration</h2>
|
||
<p>Sometimes it's useful to run Clink from a flash drive or from a network share, especially if you want to use Clink on someone else's computer.</p>
|
||
<p>Here's how you can set up a portable configuration for Clink:</p>
|
||
<ol>
|
||
<li>Put your Lua scripts and other tools in the same directory as the Clink executable files. For example fzf.exe, z.cmd, oh-my-posh.exe, or etc can all go in the same directory on a flash drive or network share.</li>
|
||
<li>Make a batch file such as <code>portable.bat</code> that injects Clink using a specific profile directory.<ul>
|
||
<li>On a flash drive, you can have a portable profile in a subdirectory under the Clink directory.</li>
|
||
<li>On a network share, you'll want to copy some initial settings into a local profile directory (a profile directory on a network share will be slow).</li>
|
||
</ul>
|
||
</li>
|
||
<li>In any cmd.exe window on any computer, you can then run the <code>portable.bat</code> script to inject Clink and have all your favorite settings and key bindings work.</li>
|
||
</ol>
|
||
<p>Here are some sample scripts:</p>
|
||
<h3 id="portablebat-on-a-flash-drive">portable.bat (on a flash drive)</h3>
|
||
<p>This sample script assumes the portable.bat script is in the Clink directory, and it uses a <code>clink_portable</code> profile directory under the Clink directory.</p>
|
||
<pre><code class="language-cmd">@echo off
|
||
rem -- Do any other desired configuration here, such as loading a doskey macro file.
|
||
call "%~dp0clink.bat" inject --profile "%~dp0clink_portable" %1 %2 %3 %4 %5 %6 %7 %8 %9
|
||
</code></pre>
|
||
<h3 id="portablebat-on-a-network-share">portable.bat (on a network share)</h3>
|
||
<p>This sample script assumes the portable.bat script is in the Clink directory, and that there is a file <code>portable_clink_settings</code> with the settings you want to copy to the local profile directory.</p>
|
||
<pre><code class="language-cmd">@echo off
|
||
if not exist "%TEMP%\clink_portable" md "%TEMP%\clink_portable" >nul
|
||
if not exist "%TEMP%\clink_portable\clink_settings" copy "%~dp0portable_clink_settings" "%TEMP%\clink_portable\clink_settings" >nul
|
||
rem -- Do any other desired configuration here, such as loading a doskey macro file.
|
||
call "%~dp0clink.bat" inject --profile "%TEMP%\clink_portable" %1 %2 %3 %4 %5 %6 %7 %8 %9
|
||
</code></pre>
|
||
<a name="configreadline"/>
|
||
|
||
<h1 id="configuring-readline">Configuring Readline</h1>
|
||
<p>Readline itself can also be configured to add custom keybindings and macros by creating a Readline init file. There is excellent documentation for all the options available to configure Readline in Readline's <a href="https://tiswww.cwru.edu/php/chet/readline/rltop.html#Documentation">manual</a>.</p>
|
||
<p>Clink searches in the directories referenced by the following environment variables and loads any <code>.inputrc</code> or <code>_inputrc</code> files present, in the order listed here:</p>
|
||
<ul>
|
||
<li><code>%CLINK_INPUTRC%</code></li>
|
||
<li>The Clink profile directory (see the "state" line from <code>clink info</code>).</li>
|
||
<li><code>%USERPROFILE%</code></li>
|
||
<li><code>%LOCALAPPDATA%</code></li>
|
||
<li><code>%APPDATA%</code></li>
|
||
<li><code>%HOME%</code></li>
|
||
</ul>
|
||
<p>Configuration in files loaded earlier can be overridden by files loaded later.</p>
|
||
<p>Other software that also uses Readline will also look for the <code>.inputrc</code> file (and possibly the <code>_inputrc</code> file too). To set macros and keybindings intended only for Clink one can use the Readline init file conditional construct like this; <code>$if clink [...] $endif</code>.</p>
|
||
<p>You can use <code>clink info</code> to find the directories and configuration files for the current Clink session.</p>
|
||
<blockquote>
|
||
<p><strong>Compatibility Notes:</strong></p>
|
||
<ul>
|
||
<li>The <code>clink_inputrc_base</code> file from v0.4.8 is no longer used.</li>
|
||
<li>For backward compatibility, <code>clink_inputrc</code> is also loaded from the above locations, but it has been deprecated and may be removed in the future.</li>
|
||
</ul>
|
||
</blockquote>
|
||
<h2 id="basic-format">Basic Format</h2>
|
||
<p>The quick version is that mostly you'll use these kinds of lines:</p>
|
||
<ul>
|
||
<li><code><span class="arg">keyname</span>: <span class="arg">command</span></code></li>
|
||
<li><code><span class="arg">keyname</span>: "<span class="arg">literal text</span>"</code></li>
|
||
<li><code><span class="arg">keyname</span>: "luafunc:<span class="arg">lua_function_name</span>"</code></li>
|
||
<li><code>set <span class="arg">varname</span> <span class="arg">value</span></code></li>
|
||
</ul>
|
||
<p>If a Readline macro begins with "luafunc:" then Clink interprets it as a Lua key binding and will invoke the named Lua function. Function names can include periods (such as <code>foo.bar</code>) but cannot include any other punctuation. See <a href="#luakeybindings">Lua Key Bindings</a> for more information.</p>
|
||
<p>Refer to the Readline <a href="https://tiswww.cwru.edu/php/chet/readline/rltop.html#Documentation">manual</a> for a more thorough explanation of the .inputrc file format, list of available commands, and list of configuration variables and their values.</p>
|
||
<p>See <a href="#keybindings">Key Bindings</a> for more information about binding keys in Clink.</p>
|
||
<h2 id="new-configuration-variables">New Configuration Variables</h2>
|
||
<p>Clink adds some new configuration variables to Readline, beyond what's described in the Readline manual:</p>
|
||
<table>
|
||
<thead>
|
||
<tr>
|
||
<th align="center">Name</th>
|
||
<th align="center">Default</th>
|
||
<th>Description</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody><tr>
|
||
<td align="center"><code>completion-auto-query-items</code></td>
|
||
<td align="center">on</td>
|
||
<td>Automatically prompts before displaying completions if they need more than half a screen page.</td>
|
||
</tr>
|
||
<tr>
|
||
<td align="center"><code>history-point-at-end-of-anchored-search</code></td>
|
||
<td align="center">off</td>
|
||
<td>Puts the cursor at the end of the line when using <code>history-search-forward</code> or <code>history-search-backward</code>.</td>
|
||
</tr>
|
||
<tr>
|
||
<td align="center"><code>menu-complete-wraparound</code></td>
|
||
<td align="center">on</td>
|
||
<td>The <code>menu-complete</code> family of commands wraps around when reaching the end of the possible completions.</td>
|
||
</tr>
|
||
<tr>
|
||
<td align="center"><code>search-ignore-case</code></td>
|
||
<td align="center">on</td>
|
||
<td>Controls whether the history search commands ignore case.</td>
|
||
</tr>
|
||
</tbody></table>
|
||
<h2 id="new-commands">New Commands</h2>
|
||
<p>Clink adds some new commands to Readline, beyond what's described in the Readline manual:</p>
|
||
<table>
|
||
<thead>
|
||
<tr>
|
||
<th align="center">Name</th>
|
||
<th>Description</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody><tr>
|
||
<td align="center"><code>add-history</code></td>
|
||
<td>Adds the current line to the history without executing it, and clears the editing line.</td>
|
||
</tr>
|
||
<tr>
|
||
<td align="center"><code>clink-complete-numbers</code></td>
|
||
<td>Like <code>complete</code>, but for numbers from the console screen (3 digits or more, up to hexadecimal).</td>
|
||
</tr>
|
||
<tr>
|
||
<td align="center"><code>clink-copy-cwd</code></td>
|
||
<td>Copy the current working directory to the clipboard.</td>
|
||
</tr>
|
||
<tr>
|
||
<td align="center"><code>clink-copy-line</code></td>
|
||
<td>Copy the current line to the clipboard.</td>
|
||
</tr>
|
||
<tr>
|
||
<td align="center"><code>clink-copy-word</code></td>
|
||
<td>Copy the word at the cursor to the clipboard, or copies the nth word if a numeric argument is provided via the <code>digit-argument</code> keys.</td>
|
||
</tr>
|
||
<tr>
|
||
<td align="center"><code>clink-ctrl-c</code></td>
|
||
<td>Discards the current line and starts a new one (like <kbd>Ctrl</kbd>+<kbd>C</kbd> in CMD.EXE).</td>
|
||
</tr>
|
||
<tr>
|
||
<td align="center"><code>clink-exit</code></td>
|
||
<td>Replaces the current line with <code>exit</code> and executes it (exits the shell instance).</td>
|
||
</tr>
|
||
<tr>
|
||
<td align="center"><code>clink-expand-doskey-alias</code></td>
|
||
<td>Expand the doskey alias (if any) at the beginning of the line.</td>
|
||
</tr>
|
||
<tr>
|
||
<td align="center"><code>clink-expand-env-vars</code></td>
|
||
<td>Expand the environment variable (e.g. <code>%FOOBAR%</code>) at the cursor.</td>
|
||
</tr>
|
||
<tr>
|
||
<td align="center"><code>clink-find-conhost</code></td>
|
||
<td>Activates the "Find" dialog when running in a standard console window (hosted by the OS conhost). This is equivalent to picking "Find..." from the console window's system menu.</td>
|
||
</tr>
|
||
<tr>
|
||
<td align="center"><code>clink-insert-dot-dot</code></td>
|
||
<td>Inserts <code>..\</code> at the cursor.</td>
|
||
</tr>
|
||
<tr>
|
||
<td align="center"><code>clink-mark-conhost</code></td>
|
||
<td>Activates the "Mark" mode when running in a standard console window (hosted by the OS conhost). This is equivalent to picking "Mark" from the console window's system menu.</td>
|
||
</tr>
|
||
<tr>
|
||
<td align="center"><code>clink-menu-complete-numbers</code></td>
|
||
<td>Like <code>menu-complete</code>, but for numbers from the console screen (3 digits or more, up to hexadecimal).</td>
|
||
</tr>
|
||
<tr>
|
||
<td align="center"><code>clink-menu-complete-numbers-backward</code></td>
|
||
<td>Like <code>menu-complete-backward</code>, but for numbers from the console screen (3 digits or more, up to hexadecimal).</td>
|
||
</tr>
|
||
<tr>
|
||
<td align="center"><code>clink-old-menu-complete-numbers</code></td>
|
||
<td>Like <code>old-menu-complete</code>, but for numbers from the console screen (3 digits or more, up to hexadecimal).</td>
|
||
</tr>
|
||
<tr>
|
||
<td align="center"><code>clink-old-menu-complete-numbers-backward</code></td>
|
||
<td>Like <code>old-menu-complete-backward</code>, but for numbers from the console screen (3 digits or more, up to hexadecimal).</td>
|
||
</tr>
|
||
<tr>
|
||
<td align="center"><code>clink-paste</code></td>
|
||
<td>Paste the clipboard at the cursor.</td>
|
||
</tr>
|
||
<tr>
|
||
<td align="center"><code>clink-popup-complete</code></td>
|
||
<td>Show a popup window that lists the available completions.</td>
|
||
</tr>
|
||
<tr>
|
||
<td align="center"><code>clink-popup-complete-numbers</code></td>
|
||
<td>Like <code>clink-popup-complete</code>, but for numbers from the console screen (3 digits or more, up to hexadecimal).</td>
|
||
</tr>
|
||
<tr>
|
||
<td align="center"><code>clink-popup-directories</code></td>
|
||
<td>Show a popup window of recent current working directories. In the popup, use <kbd>Enter</kbd> to <code>cd /d</code> to the highlighted directory. See below more about the popup window.</td>
|
||
</tr>
|
||
<tr>
|
||
<td align="center"><code>clink-popup-history</code></td>
|
||
<td>Show a popup window that lists the command history (if any text precedes the cursor then it uses an anchored search to filter the list). In the popup, use <kbd>Enter</kbd> to execute the highlighted command. See below for more about the popup window.</td>
|
||
</tr>
|
||
<tr>
|
||
<td align="center"><code>clink-reload</code></td>
|
||
<td>Reloads the .inputrc file and the Lua scripts.</td>
|
||
</tr>
|
||
<tr>
|
||
<td align="center"><code>clink-reset-line</code></td>
|
||
<td>Clears the current line.</td>
|
||
</tr>
|
||
<tr>
|
||
<td align="center"><code>clink-scroll-bottom</code></td>
|
||
<td>Scroll the console window to the bottom (the current input line).</td>
|
||
</tr>
|
||
<tr>
|
||
<td align="center"><code>clink-scroll-line-down</code></td>
|
||
<td>Scroll the console window down one line.</td>
|
||
</tr>
|
||
<tr>
|
||
<td align="center"><code>clink-scroll-line-up</code></td>
|
||
<td>Scroll the console window up one line.</td>
|
||
</tr>
|
||
<tr>
|
||
<td align="center"><code>clink-scroll-page-down</code></td>
|
||
<td>Scroll the console window down one page.</td>
|
||
</tr>
|
||
<tr>
|
||
<td align="center"><code>clink-scroll-page-up</code></td>
|
||
<td>Scroll the console window up one page.</td>
|
||
</tr>
|
||
<tr>
|
||
<td align="center"><code>clink-scroll-top</code></td>
|
||
<td>Scroll the console window to the top.</td>
|
||
</tr>
|
||
<tr>
|
||
<td align="center"><code>clink-show-help</code></td>
|
||
<td>Lists the currently active key bindings using friendly key names.</td>
|
||
</tr>
|
||
<tr>
|
||
<td align="center"><code>clink-show-help-raw</code></td>
|
||
<td>Lists the currently active key bindings using raw key sequences.</td>
|
||
</tr>
|
||
<tr>
|
||
<td align="center"><code>clink-up-directory</code></td>
|
||
<td>Changes to the parent directory.</td>
|
||
</tr>
|
||
<tr>
|
||
<td align="center"><code>cua-backward-char</code></td>
|
||
<td>Extends the selection and moves back a character.</td>
|
||
</tr>
|
||
<tr>
|
||
<td align="center"><code>cua-backward-word</code></td>
|
||
<td>Extends the selection and moves back a word.</td>
|
||
</tr>
|
||
<tr>
|
||
<td align="center"><code>cua-beg-of-line</code></td>
|
||
<td>Extends the selection and moves to the start of the current line.</td>
|
||
</tr>
|
||
<tr>
|
||
<td align="center"><code>cua-copy</code></td>
|
||
<td>Copies the selection to the clipboard.</td>
|
||
</tr>
|
||
<tr>
|
||
<td align="center"><code>cua-cut</code></td>
|
||
<td>Cuts the selection to the clipboard.</td>
|
||
</tr>
|
||
<tr>
|
||
<td align="center"><code>cua-end-of-line</code></td>
|
||
<td>Extends the selection and moves to the end of the line.</td>
|
||
</tr>
|
||
<tr>
|
||
<td align="center"><code>cua-forward-char</code></td>
|
||
<td>Extends the selection and moves forward a character.</td>
|
||
</tr>
|
||
<tr>
|
||
<td align="center"><code>cua-forward-word</code></td>
|
||
<td>Extends the selection and moves forward a word.</td>
|
||
</tr>
|
||
<tr>
|
||
<td align="center"><code>old-menu-complete-backward</code></td>
|
||
<td>Like <code>old-menu-complete</code>, but in reverse.</td>
|
||
</tr>
|
||
<tr>
|
||
<td align="center"><code>remove-history</code></td>
|
||
<td>While searching history, removes the current line from the history.</td>
|
||
</tr>
|
||
</tbody></table>
|
||
<a name="completioncolors"/>
|
||
|
||
<h2 id="completion-colors">Completion Colors</h2>
|
||
<p>When <code>colored-completion-prefix</code> is configured to <code>on</code>, then the "so" color from <code>%LS_COLORS%</code> is used to color the common prefix when displaying possible completions. The default for "so" is magenta, but for example <code>set LS_COLORS=so=90</code> sets the color to bright black (which shows up as a dark gray).</p>
|
||
<p>When <code>colored-stats</code> is configured to <code>on</code>, then the color definitions from <code>%LS_COLORS%</code> (using ANSI escape codes) are used to color file completions according to their file type or extension. Each definition is a either a two character type id or a file extension, followed by an equals sign and then the <a href="https://en.wikipedia.org/wiki/ANSI_escape_code#SGR_parameters">SGR parameters</a> for an ANSI escape code. Multiple definitions are separated by colons. Also, since <code>%LS_COLORS%</code> doesn't cover readonly files, hidden files, doskey aliases, or shell commands the <code>color.readonly</code>, <code>color.hidden</code>, <code>color.doskey</code>, and <code>color.cmd</code> <a href="#configclink">Clink settings</a> exist to cover those.</p>
|
||
<p>Here is an example where <code>%LS_COLORS%</code> defines colors for various types.</p>
|
||
<ul>
|
||
<li><code>so=</code> defines the color for the common prefix for possible completions.</li>
|
||
<li><code>fi=</code> defines the color for normal files.</li>
|
||
<li><code>di=</code> defines the color for directories.</li>
|
||
<li><code>ex=</code> defines the color for executable files.</li>
|
||
</ul>
|
||
<pre><code class="language-plaintext">set LS_COLORS=so=90:fi=97:di=93:ex=92:*.pdf=30;105:*.md=4
|
||
</code></pre>
|
||
<p>Let's break that down:</p>
|
||
<ul>
|
||
<li><code>so=90</code> uses bright black (dark gray) for the common prefix for possible completions.</li>
|
||
<li><code>fi=97</code> uses bright white for files.</li>
|
||
<li><code>di=93</code> uses bright yellow for directories.</li>
|
||
<li><code>ex=92</code> uses bright green for executable files.</li>
|
||
<li><code>*.pdf=30;105</code> uses black on bright magenta for .pdf files.</li>
|
||
<li><code>*.md=4</code> uses underline for .md files.</li>
|
||
</ul>
|
||
<h2 id="popup-window">Popup window</h2>
|
||
<p>The <code>clink-popup-complete</code>, <code>clink-popup-directories</code>, and <code>clink-popup-history</code> commands show a popup window that lists the available completions, directory history, or command history. Here's how it works:</p>
|
||
<table>
|
||
<thead>
|
||
<tr>
|
||
<th align="center">Key</th>
|
||
<th>Description</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody><tr>
|
||
<td align="center"><kbd>Escape</kbd></td>
|
||
<td>Cancels the popup.</td>
|
||
</tr>
|
||
<tr>
|
||
<td align="center"><kbd>Enter</kbd></td>
|
||
<td>Inserts the highlighted completion, changes to the highlighted directory, or executes the highlighted command.</td>
|
||
</tr>
|
||
<tr>
|
||
<td align="center"><kbd>Shift</kbd>+<kbd>Enter</kbd></td>
|
||
<td>Inserts the highlighted completion, inserts the highlighted directory, or jumps to the highlighted command history entry without executing it.</td>
|
||
</tr>
|
||
<tr>
|
||
<td align="center"><kbd>Ctrl</kbd>+<kbd>Enter</kbd></td>
|
||
<td>Same as <kbd>Shift</kbd>+<kbd>Enter</kbd>.</td>
|
||
</tr>
|
||
<tr>
|
||
<td align="center">Typing</td>
|
||
<td>Typing does an incremental search.</td>
|
||
</tr>
|
||
<tr>
|
||
<td align="center"><kbd>F3</kbd></td>
|
||
<td>Go to the next match.</td>
|
||
</tr>
|
||
<tr>
|
||
<td align="center"><kbd>Ctrl</kbd>+<kbd>L</kbd></td>
|
||
<td>Go to the next match.</td>
|
||
</tr>
|
||
<tr>
|
||
<td align="center"><kbd>Shift</kbd>+<kbd>F3</kbd></td>
|
||
<td>Go to the previous match.</td>
|
||
</tr>
|
||
<tr>
|
||
<td align="center"><kbd>Ctrl</kbd>+<kbd>Shift</kbd>+<kbd>L</kbd></td>
|
||
<td>Go to the previous match.</td>
|
||
</tr>
|
||
</tbody></table>
|
||
<h1 id="extending-clink">Extending Clink</h1>
|
||
<p>The Readline library allows clients to offer an alternative path for creating completion matches. Clink uses this to hook Lua into the completion process making it possible to script the generation of matches with <a href="https://www.lua.org/docs.html">Lua</a> scripts. The following sections describe this in more detail and show some examples.</p>
|
||
<a name="lua-scripts-location"/>
|
||
|
||
<h2 id="the-location-of-lua-scripts">The Location of Lua Scripts</h2>
|
||
<p>Clink loads all Lua scripts it finds in these directories:</p>
|
||
<ol>
|
||
<li>All directories listed in the <code>clink.path</code> setting, separated by semicolons.</li>
|
||
<li>If <code>clink.path</code> is not set, then the DLL directory and the profile directory are used (see <a href="#filelocations">File Locations</a> for info about the profile directory).</li>
|
||
<li>All directories listed in the <code>%CLINK_PATH%</code> environment variable, separated by semicolons.</li>
|
||
<li>All directories registered by the <code>clink installscripts</code> command.</li>
|
||
</ol>
|
||
<p>Lua scripts are loaded once and are only reloaded if forced because the scripts locations change, the <code>clink-reload</code> command is invoked (<kbd>Ctrl</kbd>+<kbd>X</kbd>,<kbd>Ctrl</kbd>+<kbd>R</kbd>), or the <code>lua.reload_scripts</code> setting changes (or is True).</p>
|
||
<p>Run <code>clink info</code> to see the script paths for the current session.</p>
|
||
<a name="matchgenerators"/>
|
||
|
||
<h2 id="match-generators">Match Generators</h2>
|
||
<p>These are Lua functions that are called as part of Readline's completion process.</p>
|
||
<p>First create a match generator object:</p>
|
||
<pre><code class="language-lua">local my_generator = clink.generator(priority)
|
||
</code></pre>
|
||
<p>The <span class="arg">priority</span> argument is a number that influences when the generator gets called, with lower numbers going before higher numbers.</p>
|
||
<h3 id="the-generate-function">The :generate() Function</h3>
|
||
<p>Next define a match generator function on the object, taking the following form:</p>
|
||
<pre><code class="language-lua">function my_generator:generate(line_state, match_builder)
|
||
-- Use the line_state object to examine the current line and create matches.
|
||
-- Submit matches to Clink using the match_builder object.
|
||
-- Return true or false.
|
||
end
|
||
</code></pre>
|
||
<p><span class="arg">line_state</span> is a <a href="#line">line</a> object that has information about the current line.</p>
|
||
<p><span class="arg">match_builder</span> is a <a href="#builder">builder</a> object to which matches can be added.</p>
|
||
<p>If no further match generators need to be called then the function should return true. Returning false or nil continues letting other match generators get called.</p>
|
||
<p>Here is an example script that supplies git branch names as matches for <code>git checkout</code>. It's based on git_branch_autocomplete.lua from <a href="https://github.com/collink/clink-git-extensions">collink.clink-git-extensions</a>. The version here is updated for the new Clink Lua API, and for illustration purposes it's been simplified to not support git aliases.</p>
|
||
<pre><code class="language-lua">local git_branch_autocomplete = clink.generator(1)
|
||
|
||
local function string.starts(str, start)
|
||
return string.sub(str, 1, string.len(start)) == start
|
||
end
|
||
|
||
local function is_checkout_ac(text)
|
||
if string.starts(text, "git checkout") then
|
||
return true
|
||
end
|
||
return false
|
||
end
|
||
|
||
local function get_branches()
|
||
-- Run git command to get branches.
|
||
local handle = io.popen("git branch -a 2>&1")
|
||
local result = handle:read("*a")
|
||
handle:close()
|
||
-- Parse the branches from the output.
|
||
local branches = {}
|
||
if string.starts(result, "fatal") == false then
|
||
for branch in string.gmatch(result, " %S+") do
|
||
branch = string.gsub(branch, " ", "")
|
||
if branch ~= "HEAD" then
|
||
table.insert(branches, branch)
|
||
end
|
||
end
|
||
end
|
||
return branches
|
||
end
|
||
|
||
function git_branch_autocomplete:generate(line_state, match_builder)
|
||
-- Check if it's a checkout command.
|
||
if not is_checkout_ac(line_state:getline()) then
|
||
return false
|
||
end
|
||
-- Get branches and add them (does nothing if not in a git repo).
|
||
local matchCount = 0
|
||
for _, branch in ipairs(get_branches()) do
|
||
match_builder:addmatch(branch)
|
||
matchCount = matchCount + 1
|
||
end
|
||
-- If we found branches, then stop other match generators.
|
||
return matchCount > 0
|
||
end
|
||
</code></pre>
|
||
<h3 id="the-getwordbreakinfo-function">The :getwordbreakinfo() Function</h3>
|
||
<p>A generator can influence word breaking for the end word by defining a <code>:getwordbreakinfo()</code> function. The function takes a <span class="arg">line_state</span> <a href="#line">line</a> object that has information about the current line. If it returns nil or 0, the end word is truncated to 0 length. This is the normal behavior, which allows Clink to collect and cache all matches and then filter them based on typing. Or it can return two numbers: word break length and an optional end word length. The end word is split at the word break length: one word contains the first word break length characters from the end word (if 0 length then it's discarded), and the next word contains the rest of the end word truncated to the optional word length (0 if omitted).</p>
|
||
<p>For example, when the environment variable match generator sees the end word is <code>abc%USER</code> it returns <code>3,1</code> so that the last two words become "abc" and "%" so that its generator knows it can do environment variable matching. But when it sees <code>abc%FOO%def</code> it returns <code>8,0</code> so that the last two words become "abc%FOO%" and "" so that its generator won't do environment variable matching, and also so other generators can produce matches for what follows, since "%FOO%" is an already-completed environment variable and therefore should behave like a word break. In other words, it breaks the end word differently depending on whether the number of percent signs is odd or even, to account for environent variable syntax rules.</p>
|
||
<p>And when an argmatcher sees the end word begins with a flag character it returns <code>0,1</code> so the end word contains only the flag character in order to switch from argument matching to flag matching.</p>
|
||
<blockquote>
|
||
<p><strong>Note:</strong> The <code>:getwordbreakinfo()</code> function is called very often, so it needs to be very fast or it can cause responsiveness problems while typing.</p>
|
||
</blockquote>
|
||
<pre><code class="language-lua">local envvar_generator = clink.generator(10)
|
||
|
||
function envvar_generator:generate(line_state, match_builder)
|
||
-- Does the word end with a percent sign?
|
||
local word = line_state:getendword()
|
||
if word:sub(-1) ~= "%" then
|
||
return false
|
||
end
|
||
|
||
-- Add env vars as matches.
|
||
for _, i in ipairs(os.getenvnames()) do
|
||
match_builder:addmatch("%"..i.."%", "word")
|
||
end
|
||
|
||
match_builder:setsuppressappend() -- Don't append a space character.
|
||
match_builder:setsuppressquoting() -- Don't quote envvars.
|
||
return true
|
||
end
|
||
|
||
function envvar_generator:getwordbreakinfo(line_state)
|
||
local word = line_state:getendword()
|
||
local in_out = false
|
||
local index = nil
|
||
|
||
-- Paired percent signs denote already-completed environment variables.
|
||
-- So use envvar completion for abc%foo%def%USER but not for abc%foo%USER.
|
||
for i = 1, #word do
|
||
if word:sub(i, i) == "%" then
|
||
in_out = not in_out
|
||
if in_out then
|
||
index = i - 1
|
||
else
|
||
index = i
|
||
end
|
||
end
|
||
end
|
||
|
||
-- If there were any percent signs, return word break info to influence the
|
||
-- match generators.
|
||
if index then
|
||
return index, (in_out and 1) or 0
|
||
end
|
||
end
|
||
</code></pre>
|
||
<a name="argumentcompletion"/>
|
||
|
||
<h2 id="argument-completion">Argument Completion</h2>
|
||
<p>Clink provides a framework for writing complex argument match generators in Lua. It works by creating a parser object that describes a command's arguments and flags and then registering the parser with Clink. When Clink detects the command is being entered on the current command line being edited, it uses the parser to generate matches.</p>
|
||
<p>Here is an example of a simple parser for the command <code>foobar</code>;</p>
|
||
<pre><code class="language-lua">clink.argmatcher("foobar")
|
||
:addflags("-foo", "-bar")
|
||
:addarg(
|
||
{ "hello", "hi" }, -- Completions for arg #1
|
||
{ "world", "wombles" } -- Completions for arg #2
|
||
)
|
||
</code></pre>
|
||
<p>This parser describes a command that has two positional arguments each with two potential options. It also has two flags which the parser considers to be position independent meaning that provided the word being completed starts with a certain prefix the parser with attempt to match the from the set of flags.</p>
|
||
<p>On the command line completion would look something like this:</p>
|
||
<pre style="border-radius:initial;border:initial"><code class="plaintext" style="background-color:black;color:#cccccc">C:>foobar hello -foo wo
|
||
wombles wonder world
|
||
C:>foobar hello -foo wo<span style="color:#ffffff">_</span>
|
||
</code></pre>
|
||
|
||
<p>When displaying possible completions, flag matches are only shown if the flag character has been input (so <code>command </code> and <kbd>Alt</kbd>+<kbd>=</kbd> would list only non-flag matches, or <code>command -</code> and <kbd>Alt</kbd>+<kbd>=</kbd> would list only flag matches).</p>
|
||
<h3 id="more-advanced-stuff">More Advanced Stuff</h3>
|
||
<h4 id="linking-parsers">Linking Parsers</h4>
|
||
<p>There are often situations where the parsing of a command's arguments is dependent on the previous words (<code>git merge ...</code> compared to <code>git log ...</code> for example). For these scenarios Clink allows you to link parsers to arguments' words using Lua's concatenation operator. Parsers can also be concatenated with flags too.</p>
|
||
<pre><code class="language-lua">a_parser = clink.argmatcher():addarg({ "foo", "bar" })
|
||
b_parser = clink.argmatcher():addarg({ "abc", "123" })
|
||
c_parser = clink.argmatcher()
|
||
c_parser:addarg({ "foobar" .. a_parser }) -- Arg #1 is "foobar", which has args "foo" or "bar".
|
||
c_parser:addarg({ b_parser }) -- Arg #2 is "abc" or "123".
|
||
</code></pre>
|
||
<p>As the example above shows, it is also possible to use a parser without concatenating it to a word. When Clink follows a link to a parser it is permanent and it will not return to the previous parser.</p>
|
||
<h4 id="functions-as-argument-options">Functions As Argument Options</h4>
|
||
<p>Argument options are not limited solely to strings. Clink also accepts functions too so more context aware argument options can be used.</p>
|
||
<pre><code class="language-lua">function rainbow_function(word)
|
||
return { "red", "white", "blue" }
|
||
end
|
||
|
||
the_parser = clink.argmatcher()
|
||
the_parser:addarg({ "zippy", "bungle", "george" })
|
||
the_parser:addarg({ rainbow_function, "yellow", "green" })
|
||
</code></pre>
|
||
<p>The functions take a single argument which is a word from the command line being edited (or partial word if it is the one under the cursor). Functions should return a table of potential matches.</p>
|
||
<p>Some built-in matcher functions are available:</p>
|
||
<table>
|
||
<thead>
|
||
<tr>
|
||
<th align="center">Function</th>
|
||
<th>Description</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody><tr>
|
||
<td align="center"><a href="#clink.dirmatches">clink.dirmatches</a></td>
|
||
<td>Generates directory matches.</td>
|
||
</tr>
|
||
<tr>
|
||
<td align="center"><a href="#clink.filematches">clink.filematches</a></td>
|
||
<td>Generates file matches.</td>
|
||
</tr>
|
||
</tbody></table>
|
||
<h4 id="shorthand">Shorthand</h4>
|
||
<p>It is also possible to omit the <code>addarg</code> and <code>addflags</code> function calls and use a more declarative shorthand form:</p>
|
||
<pre><code class="language-lua">-- Shorthand form; requires tables.
|
||
clink.argmatcher()
|
||
{ "one", "won" } -- Arg #1
|
||
{ "two", "too" } -- Arg #2
|
||
{ "-a", "-b", "/?", "/h" } -- Flags
|
||
|
||
-- Normal form:
|
||
clink.argmatcher()
|
||
:addarg(
|
||
{ "one", "won" } -- Arg #1
|
||
{ "two", "too" } -- Arg #2
|
||
)
|
||
:addflags("-a", "-b", "/?", "/h") -- Flags
|
||
</code></pre>
|
||
<p>With the shorthand form flags are implied rather than declared. When a shorthand table's first value is a string starting with <code>-</code> or <code>/</code> then the table is interpreted as flags. Note that it's still possible with shorthand form to mix flag prefixes, and even add additional flag prefixes, such as <code>{ <span class="hljs-string">'-a'</span>, <span class="hljs-string">'/b'</span>, <span class="hljs-string">'=c'</span> }</code>.</p>
|
||
<a name="filteringmatchcompletions"/>
|
||
|
||
<h4 id="filtering-match-completions">Filtering Match Completions</h4>
|
||
<p>A match generator or <code>luafunc:</code> key binding can use <a href="#clink.onfiltermatches">clink.onfiltermatches()</a> to register a function that will be called after matches are generated but before they are displayed or inserted.</p>
|
||
<p>The function receives a table argument containing the matches to be displayed, a string argument indicating the completion type, and a boolean argument indicating whether filename completion is desired. The table argument has a <code>match</code> string field and a <code>type</code> string field; these are the same as in <a href="builder:addmatch">builder:addmatch()</a>.</p>
|
||
<p>The possible completion types are:</p>
|
||
<table>
|
||
<thead>
|
||
<tr>
|
||
<th>Type</th>
|
||
<th>Description</th>
|
||
<th>Example</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody><tr>
|
||
<td><code>"?"</code></td>
|
||
<td>List the possible completions.</td>
|
||
<td><code>possible-completions</code> or <code>popup-complete</code></td>
|
||
</tr>
|
||
<tr>
|
||
<td><code>"*"</code></td>
|
||
<td>Insert all of the possible completions.</td>
|
||
<td><code>insert-completions</code></td>
|
||
</tr>
|
||
<tr>
|
||
<td><code>"\t"</code></td>
|
||
<td>Do standard completion.</td>
|
||
<td><code>complete</code></td>
|
||
</tr>
|
||
<tr>
|
||
<td><code>"!"</code></td>
|
||
<td>Do standard completion, and list all possible completions if there is more than one.</td>
|
||
<td><code>complete</code> (when the <code>show-all-if-ambiguous</code> config variable is set)</td>
|
||
</tr>
|
||
<tr>
|
||
<td><code>"@"</code></td>
|
||
<td>Do standard completion, and list all possible completions if there is more than one and partial completion is not possible.</td>
|
||
<td><code>complete</code> (when the <code>show-all-if-unmodified</code> config variable is set)</td>
|
||
</tr>
|
||
<tr>
|
||
<td><code>"%"</code></td>
|
||
<td>Do menu completion (cycle through possible completions).</td>
|
||
<td><code>menu-complete</code> or <code>old-menu-complete</code></td>
|
||
</tr>
|
||
</tbody></table>
|
||
<p>The return value is a table with the input matches filtered as desired. The match filter function can remove matches, but cannot add matches (use a match generator instead). If only one match remains after filtering, then many commands will insert the match without displaying it. This makes it possible to spawn a process (such as <a href="https://github.com/junegunn/fzf">fzf</a>) to perform enhanced completion by interactively filtering the matches and keeping only one selected match.</p>
|
||
<pre><code class="language-lua">settings.add("fzf.height", "40%", "Height to use for the --height flag")
|
||
settings.add("fzf.exe_location", "", "Location of fzf.exe if not on the PATH")
|
||
|
||
-- Build a command line to launch fzf.
|
||
local function get_fzf()
|
||
local height = settings.get("fzf.height")
|
||
local command = settings.get("fzf.exe_location")
|
||
if not command or command == "" then
|
||
command = "fzf.exe"
|
||
else
|
||
command = os.getshortname(command)
|
||
end
|
||
if height and height ~= "" then
|
||
command = command..' --height '..height
|
||
end
|
||
return command
|
||
end
|
||
|
||
local fzf_complete_intercept = false
|
||
|
||
-- Sample key binding in .inputrc:
|
||
-- M-C-x: "luafunc:fzf_complete"
|
||
function fzf_complete(rl_buffer)
|
||
fzf_complete_intercept = true
|
||
rl.invokecommand("complete")
|
||
if fzf_complete_intercept then
|
||
rl_buffer:ding()
|
||
end
|
||
fzf_complete_intercept = false
|
||
rl_buffer:refreshline()
|
||
end
|
||
|
||
local function filter_matches(matches, completion_type, filename_completion_desired)
|
||
if not fzf_complete_intercept then
|
||
return
|
||
end
|
||
-- Start fzf.
|
||
local r,w = io.popenrw(get_fzf()..' --layout=reverse-list')
|
||
if not r or not w then
|
||
return
|
||
end
|
||
-- Write matches to the write pipe.
|
||
for _,m in ipairs(matches) do
|
||
w:write(m.match.."\n")
|
||
end
|
||
w:close()
|
||
-- Read filtered matches.
|
||
local ret = {}
|
||
while (true) do
|
||
local line = r:read('*line')
|
||
if not line then
|
||
break
|
||
end
|
||
for _,m in ipairs(matches) do
|
||
if m.match == line then
|
||
table.insert(ret, m)
|
||
end
|
||
end
|
||
end
|
||
r:close()
|
||
-- Yay, successful; clear it to not ding.
|
||
fzf_complete_intercept = false
|
||
return ret
|
||
end
|
||
|
||
local interceptor = clink.generator(0)
|
||
function interceptor:generate(line_state, match_builder)
|
||
-- Only intercept when the specific command was used.
|
||
if fzf_complete_intercept then
|
||
clink.onfiltermatches(filter_matches)
|
||
end
|
||
return false
|
||
end
|
||
</code></pre>
|
||
<a name="filteringthematchdisplay"/>
|
||
|
||
<h4 id="filtering-the-match-display">Filtering The Match Display</h4>
|
||
<p>In some instances it may be preferable to display potential matches in an alternative form than the generated matches passed to and used internally by Readline. For example, it might be desirable to display a <code>*</code> next to some matches, or to show additional information about each match. Filtering the match display only affects what is displayed; it doesn't affect completing matches.</p>
|
||
<p>A match generator can use <a href="#clink.ondisplaymatches">clink.ondisplaymatches()</a> to register a function that will be called before matches are displayed (this is reset every time match generation is invoked).</p>
|
||
<p>The function receives a table argument containing the matches to be displayed, and a boolean argument indicating whether they'll be displayed in a popup window. The table argument has a <code>match</code> string field and a <code>type</code> string field; these are the same as in <a href="builder:addmatch">builder:addmatch()</a>. The return value is a table with the input matches filtered as required by the match generator. The returned table can also optionally include a <code>display</code> string field and a <code>description</code> string field. When present, <code>display</code> will be displayed as the match instead of the <code>match</code> field, and <code>description</code> will be displayed next to the match. Putting the description in a separate field enables Clink to align the descriptions in a column.</p>
|
||
<pre><code class="language-lua">local function my_filter(matches, popup)
|
||
local new_matches = {}
|
||
for _,m in ipairs(matches) do
|
||
if m.match:find("[0-9]") then
|
||
-- Ignore matches with one or more digits.
|
||
else
|
||
-- Keep the match, and also add * prefix to directory matches.
|
||
if m.type:find("^dir") then
|
||
m.display = "*"..m.match
|
||
end
|
||
table.insert(new_matches, m)
|
||
end
|
||
end
|
||
return new_matches
|
||
end
|
||
|
||
function my_match_generator:generate(line_state, match_builder)
|
||
...
|
||
clink.ondisplaymatches(my_filter)
|
||
end
|
||
</code></pre>
|
||
<p/>
|
||
|
||
<blockquote>
|
||
<p><strong>Compatibility Note:</strong> When a match display filter has been set, it changes how match generation behaves.</p>
|
||
<ul>
|
||
<li>When a match display filter is set, then match generation is also re-run whenever matches are displayed.</li>
|
||
<li>Normally match generation only happens at the start of a new word. The full set of potential matches is remembered and dynamically filtered based on further typing.</li>
|
||
<li>So if a match generator made contextual decisions during match generation (other than filtering) then it could potentially behave differently in Clink v1.x than it did in v0.x.</li>
|
||
</ul>
|
||
</blockquote>
|
||
<a name="classifywords"/>
|
||
|
||
<h2 id="coloring-the-input-text">Coloring The Input Text</h2>
|
||
<p>When the <code>clink.colorize_input</code> setting is enabled, <a href="#argumentcompletion">argmatcher</a> automatically apply colors to the input text by parsing it.</p>
|
||
<p>It's possible for an argmatcher to provide a function to override how its arguments are colored. This function is called once for each of the argmatcher's arguments.</p>
|
||
<p>It's also possible to register a classifier function for the whole input line. This function is very similar to a match generator; classifier functions are called in priority order, and a classifier can choose to stop the classification process.</p>
|
||
<h4 id="setting-a-classifier-function-in-an-argmatcher">Setting a classifier function in an argmatcher</h4>
|
||
<p>In cases where an <a href="#argumentcompletion">argmatcher</a> isn't able to color the input text in the desired manner, it's possible to supply a classifier function that overrides how the argmatcher colors the input text. An argmatcher's classifier function is called once for each word the argmatcher parses, but it can classify any words (not just the word it was called for). Each argmatcher can have its own classifier function, so when there are linked argmatchers more than one function may be invoked.</p>
|
||
<p>Words are colored by classifying the words, and each classification has an associated color. See <a href="#word_classifications:classifyword">word_classifications:classifyword()</a> for the available classification codes.</p>
|
||
<p>The <code>clink set</code> command has different syntax depending on the setting type, so the argmatcher for <code>clink</code> needs help in order to get everything right. A custom generator function parses the input text to provide appropriate matches, and a custom classifier function applies appropriate coloring.</p>
|
||
<pre><code class="language-lua">-- In this example, the argmatcher matches a directory as the first argument and
|
||
-- a file as the second argument. It uses a word classifier function to classify
|
||
-- directories (words that end with a path separator) as "unexpected" in the
|
||
-- second argument position.
|
||
|
||
local function classify_handler(arg_index, word, word_index, line_state, classifications)
|
||
-- `arg_index` is the argument position in the argmatcher.
|
||
-- In this example only position 2 needs special treatent.
|
||
if arg_index ~= 2 then
|
||
return
|
||
end
|
||
|
||
-- `arg_index` is the argument position in the argmatcher.
|
||
-- `word_index` is the word position in the `line_state`.
|
||
-- Ex1: in `samp dir file` for the word `dir` the argument index is 1 and
|
||
-- the word index is 2.
|
||
-- Ex2: in `samp --help dir file` for the word `dir` the argument index is
|
||
-- still 1, but the word index is 3.
|
||
|
||
-- `word` is the word the classifier function was called for and `word_index`
|
||
-- is its position in the line. Because `line_state` is also provided, the
|
||
-- function can examine any words in the input line.
|
||
if word:sub(-1) == "\\" then
|
||
-- The word appears to be a directory, but this example expects only
|
||
-- files in argument position 2. Here the word gets classified as "n"
|
||
-- (unexpected) so it gets colored differently.
|
||
classifications:classifyword(word_index, "n")
|
||
end
|
||
end
|
||
|
||
local matcher = clink.argmatcher("samp")
|
||
:addflags("--help")
|
||
:addarg({ clink.dirmatches })
|
||
:addarg({ clink.filematches })
|
||
:setclassifier(classify_handler)
|
||
</code></pre>
|
||
<h4 id="setting-a-classifier-function-for-the-whole-input-line">Setting a classifier function for the whole input line</h4>
|
||
<p>In some cases it may be desireable to use a custom classifier to apply coloring in an input line.</p>
|
||
<p>First create a classifier object:</p>
|
||
<pre><code class="language-lua">local my_classifier = clink.classifier(priority)
|
||
</code></pre>
|
||
<p>The <span class="arg">priority</span> argument is a number that influences when the classifier gets called, with lower numbers going before higher numbers.</p>
|
||
<p>Next define a classify function on the object, taking the following form:</p>
|
||
<pre><code class="language-lua">function my_classifier:classify(commands)
|
||
-- commands is a table of { line_state, classifications } objects, one per
|
||
-- command in the input line. For example, "echo hello & echo world" is two
|
||
-- commands: "echo hello" and "echo world".
|
||
end
|
||
</code></pre>
|
||
<p><span class="arg">commands</span> is a table of tables, with the following scheme:
|
||
<span class="tablescheme">{ {line_state:<a href="#line">line</a>, classifications:<a href="#word_classifications">word_classifications</a>}, ... }</span>.</p>
|
||
<p>If no further classifiers need to be called then the function should return true. Returning false or nil continues letting other classifiers get called.</p>
|
||
<pre><code class="language-lua">-- In this example, a custom classifier applies colors to command separators and
|
||
-- redirection symbols in the input line.
|
||
local cmdsep_classifier = clink.classifier(50)
|
||
function cmdsep_classifier:classify(commands)
|
||
-- The `classifications:classifyword()` method can only affect the words for
|
||
-- the corresponding command. However, this example doesn't need to parse
|
||
-- words within commands, it just wants to parse the whole line. And since
|
||
-- each command's `classifications:applycolor()` method can apply color
|
||
-- anywhere in the entire input line, this example can simply use the first
|
||
-- command's `classifications` object.
|
||
if commands[1] then
|
||
local line_state = commands[1].line_state
|
||
local classifications = commands[1].classifications
|
||
local line = line_state:getline()
|
||
local quote = false
|
||
local i = 1
|
||
while (i <= #line) do
|
||
local c = line:sub(i,i)
|
||
if c == '^' then
|
||
i = i + 1
|
||
elseif c == '"' then
|
||
quote = not quote
|
||
elseif quote then
|
||
elseif c == '&' or c == '|' then
|
||
classifications:applycolor(i, 1, "95")
|
||
elseif c == '>' or c == '<' then
|
||
classifications:applycolor(i, 1, "35")
|
||
if line:sub(i,i+1) == '>&' then
|
||
i = i + 1
|
||
classifications:applycolor(i, 1, "35")
|
||
end
|
||
end
|
||
i = i + 1
|
||
end
|
||
end
|
||
end
|
||
</code></pre>
|
||
<a name="customisingtheprompt"/>
|
||
|
||
<h2 id="customising-the-prompt">Customising The Prompt</h2>
|
||
<p>Before Clink displays the prompt it filters the prompt through Lua so that the prompt can be customised. This happens each and every time that the prompt is shown which allows for context sensitive customisations (such as showing the current branch of a git repository).</p>
|
||
<p>Writing a prompt filter is straightforward:</p>
|
||
<ol>
|
||
<li>Create a new prompt filter by calling <code>clink.promptfilter()</code> along with a priority id which dictates the order in which filters are called. Lower priority ids are called first.</li>
|
||
<li>Define a <code>filter()</code> function on the returned prompt filter.</li>
|
||
</ol>
|
||
<p>The filter function takes a string argument that contains the filtered prompt so far. If the filter function returns nil, it has no effect. If the filter function returns a string, that string is used as the new filtered prompt (and may be further modified by other prompt filters with higher priority ids). If the filter function returns a string and a boolean, then if the boolean is false the prompt filtering is done and no further filter functions are called.</p>
|
||
<pre><code class="language-lua">local p = clink.promptfilter(30)
|
||
function p:filter(prompt)
|
||
return "new prefix "..prompt.." new suffix" -- Add ,false to stop filtering.
|
||
end
|
||
</code></pre>
|
||
<p>The following example illustrates setting the prompt, modifying the prompt, using ANSI escape code for colors, running a git command to find the current branch, and stopping any further processing.</p>
|
||
<pre><code class="language-lua">local green = "\x1b[92m"
|
||
local yellow = "\x1b[93m"
|
||
local cyan = "\x1b[36m"
|
||
local normal = "\x1b[m"
|
||
|
||
-- A prompt filter that discards any prompt so far and sets the
|
||
-- prompt to the current working directory. An ANSI escape code
|
||
-- colors it yellow.
|
||
local cwd_prompt = clink.promptfilter(30)
|
||
function cwd_prompt:filter(prompt)
|
||
return yellow..os.getcwd()..normal
|
||
end
|
||
|
||
-- A prompt filter that inserts the date at the beginning of the
|
||
-- the prompt. An ANSI escape code colors the date green.
|
||
local date_prompt = clink.promptfilter(40)
|
||
function date_prompt:filter(prompt)
|
||
return green..os.date("%a %H:%M")..normal.." "..prompt
|
||
end
|
||
|
||
-- A prompt filter that may stop further prompt filtering.
|
||
-- This is a silly example, but on Wednesdays, it stops the
|
||
-- filtering, which in this example prevents git branch
|
||
-- detection and the line feed and angle bracket.
|
||
local wednesday_silliness = clink.promptfilter(45)
|
||
function wednesday_silliness:filter(prompt)
|
||
if os.date("%a") == "Wed" then
|
||
-- The ,false stops any further filtering.
|
||
return prompt.." HAPPY HUMP DAY! ", false
|
||
end
|
||
end
|
||
|
||
-- A prompt filter that appends the current git branch.
|
||
local git_branch_prompt = clink.promptfilter(50)
|
||
function git_branch_prompt:filter(prompt)
|
||
for line in io.popen("git branch 2>nul"):lines() do
|
||
local branch = line:match("%* (.+)$")
|
||
if branch then
|
||
return prompt.." "..cyan.."["..branch.."]"..normal
|
||
end
|
||
end
|
||
end
|
||
|
||
-- A prompt filter that adds a line feed and angle bracket.
|
||
local bracket_prompt = clink.promptfilter(150)
|
||
function bracket_prompt:filter(prompt)
|
||
return prompt.."\n> "
|
||
end
|
||
</code></pre>
|
||
<p>The resulting prompt will look like this:</p>
|
||
<pre style="border-radius:initial;border:initial"><code class="plaintext" style="background-color:black"><span style="color:#00ff00">Wed 12:54</span> <span style="color:#ffff00">c:\dir</span> <span style="color:#008080">[master]</span>
|
||
<span style="color:#cccccc">> _</span>
|
||
</code></pre>
|
||
|
||
<p>...except on Wednesdays, when it will look like this:</p>
|
||
<pre style="border-radius:initial;border:initial"><code class="plaintext" style="background-color:black"><span style="color:#00ff00">Wed 12:54</span> <span style="color:#ffff00">c:\dir</span> <span style="color:#cccccc">HAPPY HUMP DAY! _</span>
|
||
</code></pre>
|
||
|
||
<p/>
|
||
|
||
<a name="escapecodes"/>
|
||
|
||
<h3 id="ansi-escape-codes-in-the-prompt-string">ANSI escape codes in the prompt string</h3>
|
||
<p>Readline needs to be told which characters in the prompt are unprintable or invisible. To help with that, Clink automatically detects most standard ANSI escape codes (and most of ConEmu's non-standard escape codes) and the BEL character (^G, audible bell) and surrounds them with <code>\001</code> (^A) and <code>\002</code> (^B) characters. For any other unprintable characters, the <code>\001</code> and <code>\002</code> characters need to be added manually. Otherwise Readline misinterprets the length of the prompt and can display the prompt and input line incorrectly in some cases (especially if the input line wraps onto a second line).</p>
|
||
<h1 id="miscellaneous">Miscellaneous</h1>
|
||
<a name="keybindings"/>
|
||
|
||
<h2 id="key-bindings">Key bindings</h2>
|
||
<p>Key bindings are defined in .inputrc files. See the <a href="#configreadline">Configuring Readline</a> section for more information.</p>
|
||
<p>Here is the quick version:</p>
|
||
<ul>
|
||
<li>A key binding is <code><em>name</em>: <em>function</em></code> or <code><em>name</em>: "<em>literal text</em>"</code>.</li>
|
||
<li>Key names are like this:<ul>
|
||
<li><code>C-a</code> and <code>"\C-a"</code> are both <kbd>Ctrl</kbd>+<kbd>a</kbd>.</li>
|
||
<li><code>M-a</code> and <code>"\M-a"</code> are both <kbd>Alt</kbd>+<kbd>a</kbd>.</li>
|
||
<li><code>M-C-a</code> and <code>"\M-\C-a"</code> are both <kbd>Alt</kbd>+<kbd>Ctrl</kbd>+<kbd>a</kbd>.</li>
|
||
<li><code>hello</code> is just <kbd>h</kbd>; the <code>ello</code> is a syntax error and is silently discarded by Readline.</li>
|
||
<li><code>"hello"</code> is the series of keys <kbd>h</kbd>,<kbd>e</kbd>,<kbd>l</kbd>,<kbd>l</kbd>,<kbd>o</kbd>.</li>
|
||
<li>Special keys like <kbd>Up</kbd> are represented by VT220 escape codes such as<code>"\e[A"</code> (see table below for more info).</li>
|
||
</ul>
|
||
</li>
|
||
<li>Key bindings can be either functions or macros (literal text):<ul>
|
||
<li><code>blah-blah</code> binds to a function named "blah-blah".</li>
|
||
<li><code>"blah-blah"</code> inserts the literal text "blah-blah".</li>
|
||
</ul>
|
||
</li>
|
||
</ul>
|
||
<p>You can use <code>clink info</code> to find the directories and configuration files for the current Clink session.</p>
|
||
<p>Here is an example <code>.inputrc</code> file with the key bindings that I use myself:</p>
|
||
<pre><code class="plaintext"><span class="hljs-meta">$if clink</span> <span class="hljs-comment"># begin clink-only section</span>
|
||
|
||
<span class="hljs-comment"># The following key bindings are for emacs mode.</span>
|
||
<span class="hljs-meta">set keymap emacs</span>
|
||
|
||
<span class="hljs-comment"># Completion key bindings.</span>
|
||
<span class="hljs-string">"\t"</span>: old-menu-complete <span class="hljs-comment"># Tab</span>
|
||
<span class="hljs-string">"\e[Z"</span>: old-menu-complete-backward <span class="hljs-comment"># Shift+Tab</span>
|
||
<span class="hljs-string">"\e[27;5;9~"</span>: clink-popup-complete <span class="hljs-comment"># Ctrl+Tab (ConEmu needs additional configuration to allow Ctrl+Tab)</span>
|
||
<span class="hljs-string">"\x1b[27;5;32~"</span>: complete <span class="hljs-comment"># Ctrl+Space</span>
|
||
|
||
<span class="hljs-comment"># Some key bindings I got used to from 4Dos/4NT/Take Command.</span>
|
||
C-b: <span class="hljs-comment"># Ctrl+B (cleared because I redefined Ctrl+F)</span>
|
||
C-d: remove-history <span class="hljs-comment"># Ctrl+D (replaces `delete-char`)</span>
|
||
C-f: clink-expand-doskey-alias <span class="hljs-comment"># Ctrl+F (replaces `forward-char`)</span>
|
||
C-k: add-history <span class="hljs-comment"># Ctrl+K (replaces `kill-line`)</span>
|
||
<span class="hljs-string">"\e[A"</span>: history-search-backward <span class="hljs-comment"># Up (replaces `previous-history`)</span>
|
||
<span class="hljs-string">"\e[B"</span>: history-search-forward <span class="hljs-comment"># Down (replaces `next-history`)</span>
|
||
<span class="hljs-string">"\e[5~"</span>: clink-popup-history <span class="hljs-comment"># PgUp (replaces `history-search-backward`)</span>
|
||
<span class="hljs-string">"\e[6~"</span>: <span class="hljs-comment"># PgDn (cleared because I redefined PgUp)</span>
|
||
<span class="hljs-string">"\e[1;5F"</span>: end-of-line <span class="hljs-comment"># Ctrl+End (replaces `kill-line`)</span>
|
||
<span class="hljs-string">"\e[1;5H"</span>: beginning-of-line <span class="hljs-comment"># Ctrl+Home (replaces `backward-kill-line`)</span>
|
||
|
||
<span class="hljs-comment"># Some key bindings handy in default (conhost) console windows.</span>
|
||
M-b: <span class="hljs-comment"># Alt+B (cleared because I redefined Alt+F)</span>
|
||
M-f: clink-find-conhost <span class="hljs-comment"># Alt+F for "Find..." from the console's system menu</span>
|
||
M-m: clink-mark-conhost <span class="hljs-comment"># Alt+M for "Mark" from the console's system menu</span>
|
||
|
||
<span class="hljs-comment"># Some key bindings for interrogating the Readline configuration.</span>
|
||
<span class="hljs-string">"\C-x\C-f"</span>: dump-functions <span class="hljs-comment"># Ctrl+X, Ctrl+F</span>
|
||
<span class="hljs-string">"\C-x\C-m"</span>: dump-macros <span class="hljs-comment"># Ctrl+X, Ctrl+M</span>
|
||
<span class="hljs-string">"\C-x\C-v"</span>: dump-variables <span class="hljs-comment"># Ctrl+X, Ctrl+V</span>
|
||
|
||
<span class="hljs-comment"># Misc other key bindings.</span>
|
||
<span class="hljs-string">"\e[5;6~"</span>: clink-popup-directories <span class="hljs-comment"># Ctrl+Shift+PgUp</span>
|
||
C-_: kill-line <span class="hljs-comment"># Ctrl+- (replaces `undo`)</span>
|
||
|
||
<span class="hljs-meta">$endif</span> <span class="hljs-comment"># end clink-only section</span>
|
||
</code></pre>
|
||
|
||
<p>The <code>clink-show-help</code> command is bound to <kbd>Alt</kbd>+<kbd>H</kbd> and lists all currently active key bindings. The list displays "friendly" key names, and these names are generally not suitable for use in .inputrc files. For example "Up" is the friendly name for <code>"\e[A"</code>, and "A-C-F2" is the friendly name for <code>"\e\e[1;5Q"</code>. To see key sequence strings suitable for use in .inputrc files use <code>clink echo</code> or <kbd>Alt</kbd>+<kbd>Shift</kbd>+<kbd>H</kbd>.</p>
|
||
<blockquote>
|
||
<p><strong>Note:</strong> Third party console hosts such as ConEmu may have their own key bindings that supersede Clink. They usually have documentation for how to change or disable their key bindings to allow console programs to handle the keys instead.</p>
|
||
</blockquote>
|
||
<h3 id="discovering-clink-key-sequences">Discovering Clink key sequences</h3>
|
||
<p>Clink provides an easy way to find the key sequence for any key combination that Clink supports. Run <code>clink echo</code> and then press key combinations; the associated key binding sequence is printed to the console output and can be used for a key binding in the inputrc file.</p>
|
||
<p>A chord can be formed by concatenating multiple key binding sequences. For example, <code>"\C-X"</code> and <code>"\e[H"</code> can be concatenated to form <code>"\C-X\e[H"</code> representing the chord <kbd>Ctrl</kbd>+<kbd>X</kbd>,<kbd>Home</kbd>.</p>
|
||
<h3 id="binding-special-keys">Binding special keys</h3>
|
||
<p>Here is a table of the key binding sequences for the special keys. Clink primarily uses VT220 emulation for keyboard input, but also uses some Xterm extended key sequences.</p>
|
||
<table>
|
||
<thead>
|
||
<tr>
|
||
<th align="center"></th>
|
||
<th align="center">Normal</th>
|
||
<th align="center">Shift</th>
|
||
<th align="center">Ctrl</th>
|
||
<th align="center">Ctrl+Shift</th>
|
||
<th align="center">Alt</th>
|
||
<th align="center">Alt+Shift</th>
|
||
<th align="center">Alt+Ctrl</th>
|
||
<th align="center">Alt+Ctrl+Shift</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody><tr>
|
||
<td align="center">Up</td>
|
||
<td align="center"><code>\e[A</code></td>
|
||
<td align="center"><code>\e[1;2A</code></td>
|
||
<td align="center"><code>\e[1;5A</code></td>
|
||
<td align="center"><code>\e[1;6A</code></td>
|
||
<td align="center"><code>\e[1;3A</code></td>
|
||
<td align="center"><code>\e[1;4A</code></td>
|
||
<td align="center"><code>\e[1;7A</code></td>
|
||
<td align="center"><code>\e[1;8A</code></td>
|
||
</tr>
|
||
<tr>
|
||
<td align="center">Down</td>
|
||
<td align="center"><code>\e[B</code></td>
|
||
<td align="center"><code>\e[1;2B</code></td>
|
||
<td align="center"><code>\e[1;5B</code></td>
|
||
<td align="center"><code>\e[1;6B</code></td>
|
||
<td align="center"><code>\e[1;3B</code></td>
|
||
<td align="center"><code>\e[1;4B</code></td>
|
||
<td align="center"><code>\e[1;7B</code></td>
|
||
<td align="center"><code>\e[1;8B</code></td>
|
||
</tr>
|
||
<tr>
|
||
<td align="center">Left</td>
|
||
<td align="center"><code>\e[D</code></td>
|
||
<td align="center"><code>\e[1;2D</code></td>
|
||
<td align="center"><code>\e[1;5D</code></td>
|
||
<td align="center"><code>\e[1;6D</code></td>
|
||
<td align="center"><code>\e[1;3D</code></td>
|
||
<td align="center"><code>\e[1;4D</code></td>
|
||
<td align="center"><code>\e[1;7D</code></td>
|
||
<td align="center"><code>\e[1;8D</code></td>
|
||
</tr>
|
||
<tr>
|
||
<td align="center">Right</td>
|
||
<td align="center"><code>\e[C</code></td>
|
||
<td align="center"><code>\e[1;2C</code></td>
|
||
<td align="center"><code>\e[1;5C</code></td>
|
||
<td align="center"><code>\e[1;6C</code></td>
|
||
<td align="center"><code>\e[1;3C</code></td>
|
||
<td align="center"><code>\e[1;4C</code></td>
|
||
<td align="center"><code>\e[1;7C</code></td>
|
||
<td align="center"><code>\e[1;8C</code></td>
|
||
</tr>
|
||
<tr>
|
||
<td align="center">Insert</td>
|
||
<td align="center"><code>\e[2~</code></td>
|
||
<td align="center"><code>\e[2;2~</code></td>
|
||
<td align="center"><code>\e[2;5~</code></td>
|
||
<td align="center"><code>\e[2;6~</code></td>
|
||
<td align="center"><code>\e[2;3~</code></td>
|
||
<td align="center"><code>\e[2;4~</code></td>
|
||
<td align="center"><code>\e[2;7~</code></td>
|
||
<td align="center"><code>\e[2;8~</code></td>
|
||
</tr>
|
||
<tr>
|
||
<td align="center">Delete</td>
|
||
<td align="center"><code>\e[3~</code></td>
|
||
<td align="center"><code>\e[3;2~</code></td>
|
||
<td align="center"><code>\e[3;5~</code></td>
|
||
<td align="center"><code>\e[3;6~</code></td>
|
||
<td align="center"><code>\e[3;3~</code></td>
|
||
<td align="center"><code>\e[3;4~</code></td>
|
||
<td align="center"><code>\e[3;7~</code></td>
|
||
<td align="center"><code>\e[3;8~</code></td>
|
||
</tr>
|
||
<tr>
|
||
<td align="center">Home</td>
|
||
<td align="center"><code>\e[H</code></td>
|
||
<td align="center"><code>\e[1;2H</code></td>
|
||
<td align="center"><code>\e[1;5H</code></td>
|
||
<td align="center"><code>\e[1;6H</code></td>
|
||
<td align="center"><code>\e[1;3H</code></td>
|
||
<td align="center"><code>\e[1;4H</code></td>
|
||
<td align="center"><code>\e[1;7H</code></td>
|
||
<td align="center"><code>\e[1;8H</code></td>
|
||
</tr>
|
||
<tr>
|
||
<td align="center">End</td>
|
||
<td align="center"><code>\e[F</code></td>
|
||
<td align="center"><code>\e[1;2F</code></td>
|
||
<td align="center"><code>\e[1;5F</code></td>
|
||
<td align="center"><code>\e[1;6F</code></td>
|
||
<td align="center"><code>\e[1;3F</code></td>
|
||
<td align="center"><code>\e[1;4F</code></td>
|
||
<td align="center"><code>\e[1;7F</code></td>
|
||
<td align="center"><code>\e[1;8F</code></td>
|
||
</tr>
|
||
<tr>
|
||
<td align="center">PgUp</td>
|
||
<td align="center"><code>\e[5~</code></td>
|
||
<td align="center"><code>\e[5;2~</code></td>
|
||
<td align="center"><code>\e[5;5~</code></td>
|
||
<td align="center"><code>\e[5;6~</code></td>
|
||
<td align="center"><code>\e[5;3~</code></td>
|
||
<td align="center"><code>\e[5;4~</code></td>
|
||
<td align="center"><code>\e[5;7~</code></td>
|
||
<td align="center"><code>\e[5;8~</code></td>
|
||
</tr>
|
||
<tr>
|
||
<td align="center">PgDn</td>
|
||
<td align="center"><code>\e[6~</code></td>
|
||
<td align="center"><code>\e[6;2~</code></td>
|
||
<td align="center"><code>\e[6;5~</code></td>
|
||
<td align="center"><code>\e[6;6~</code></td>
|
||
<td align="center"><code>\e[6;3~</code></td>
|
||
<td align="center"><code>\e[6;4~</code></td>
|
||
<td align="center"><code>\e[6;7~</code></td>
|
||
<td align="center"><code>\e[6;8~</code></td>
|
||
</tr>
|
||
<tr>
|
||
<td align="center">Tab</td>
|
||
<td align="center"><code>\t</code></td>
|
||
<td align="center"><code>\e[Z</code></td>
|
||
<td align="center"><code>\e[27;5;9~</code></td>
|
||
<td align="center"><code>\e[27;6;9~</code></td>
|
||
<td align="center">-</td>
|
||
<td align="center">-</td>
|
||
<td align="center">-</td>
|
||
<td align="center">-</td>
|
||
</tr>
|
||
<tr>
|
||
<td align="center">Space</td>
|
||
<td align="center"><code>Space</code></td>
|
||
<td align="center">-</td>
|
||
<td align="center"><code>\e[27;5;32~</code></td>
|
||
<td align="center"><code>\e[27;6;32~</code></td>
|
||
<td align="center">-</td>
|
||
<td align="center">-</td>
|
||
<td align="center"><code>\e[27;7;32~</code></td>
|
||
<td align="center"><code>\e[27;8;32~</code></td>
|
||
</tr>
|
||
<tr>
|
||
<td align="center">Backspace</td>
|
||
<td align="center"><code>^h</code></td>
|
||
<td align="center"><code>\e[27;2;8~</code></td>
|
||
<td align="center"><code>Rubout</code></td>
|
||
<td align="center"><code>\e[27;6;8~</code></td>
|
||
<td align="center"><code>\e^h</code></td>
|
||
<td align="center"><code>\e[27;4;8~</code></td>
|
||
<td align="center"><code>\eRubout</code></td>
|
||
<td align="center"><code>\e[27;8;8~</code></td>
|
||
</tr>
|
||
<tr>
|
||
<td align="center">Escape</td>
|
||
<td align="center"><code>\e[27;27~</code></td>
|
||
<td align="center">-</td>
|
||
<td align="center">-</td>
|
||
<td align="center">-</td>
|
||
<td align="center">-</td>
|
||
<td align="center">-</td>
|
||
<td align="center">-</td>
|
||
<td align="center">-</td>
|
||
</tr>
|
||
<tr>
|
||
<td align="center">F1</td>
|
||
<td align="center"><code>\eOP</code></td>
|
||
<td align="center"><code>\e[1;2P</code></td>
|
||
<td align="center"><code>\e[1;5P</code></td>
|
||
<td align="center"><code>\e[1;6P</code></td>
|
||
<td align="center"><code>\e\eOP</code></td>
|
||
<td align="center"><code>\e\e[1;2P</code></td>
|
||
<td align="center"><code>\e\e[1;5P</code></td>
|
||
<td align="center"><code>\e\e[1;6P</code></td>
|
||
</tr>
|
||
<tr>
|
||
<td align="center">F2</td>
|
||
<td align="center"><code>\eOQ</code></td>
|
||
<td align="center"><code>\e[1;2Q</code></td>
|
||
<td align="center"><code>\e[1;5Q</code></td>
|
||
<td align="center"><code>\e[1;6Q</code></td>
|
||
<td align="center"><code>\e\eOQ</code></td>
|
||
<td align="center"><code>\e\e[1;2Q</code></td>
|
||
<td align="center"><code>\e\e[1;5Q</code></td>
|
||
<td align="center"><code>\e\e[1;6Q</code></td>
|
||
</tr>
|
||
<tr>
|
||
<td align="center">F3</td>
|
||
<td align="center"><code>\eOR</code></td>
|
||
<td align="center"><code>\e[1;2R</code></td>
|
||
<td align="center"><code>\e[1;5R</code></td>
|
||
<td align="center"><code>\e[1;6R</code></td>
|
||
<td align="center"><code>\e\eOR</code></td>
|
||
<td align="center"><code>\e\e[1;2R</code></td>
|
||
<td align="center"><code>\e\e[1;5R</code></td>
|
||
<td align="center"><code>\e\e[1;6R</code></td>
|
||
</tr>
|
||
<tr>
|
||
<td align="center">F4</td>
|
||
<td align="center"><code>\eOS</code></td>
|
||
<td align="center"><code>\e[1;2S</code></td>
|
||
<td align="center"><code>\e[1;5S</code></td>
|
||
<td align="center"><code>\e[1;6S</code></td>
|
||
<td align="center"><code>\e\eOS</code></td>
|
||
<td align="center"><code>\e\e[1;2S</code></td>
|
||
<td align="center"><code>\e\e[1;5S</code></td>
|
||
<td align="center"><code>\e\e[1;6S</code></td>
|
||
</tr>
|
||
<tr>
|
||
<td align="center">F5</td>
|
||
<td align="center"><code>\e[15~</code></td>
|
||
<td align="center"><code>\e[15;2~</code></td>
|
||
<td align="center"><code>\e[15;5~</code></td>
|
||
<td align="center"><code>\e[15;6~</code></td>
|
||
<td align="center"><code>\e\e[15~</code></td>
|
||
<td align="center"><code>\e\e[15;2~</code></td>
|
||
<td align="center"><code>\e\e[15;5~</code></td>
|
||
<td align="center"><code>\e\e[15;6~</code></td>
|
||
</tr>
|
||
<tr>
|
||
<td align="center">F6</td>
|
||
<td align="center"><code>\e[17~</code></td>
|
||
<td align="center"><code>\e[17;2~</code></td>
|
||
<td align="center"><code>\e[17;5~</code></td>
|
||
<td align="center"><code>\e[17;6~</code></td>
|
||
<td align="center"><code>\e\e[17~</code></td>
|
||
<td align="center"><code>\e\e[17;2~</code></td>
|
||
<td align="center"><code>\e\e[17;5~</code></td>
|
||
<td align="center"><code>\e\e[17;6~</code></td>
|
||
</tr>
|
||
<tr>
|
||
<td align="center">F7</td>
|
||
<td align="center"><code>\e[18~</code></td>
|
||
<td align="center"><code>\e[18;2~</code></td>
|
||
<td align="center"><code>\e[18;5~</code></td>
|
||
<td align="center"><code>\e[18;6~</code></td>
|
||
<td align="center"><code>\e\e[18~</code></td>
|
||
<td align="center"><code>\e\e[18;2~</code></td>
|
||
<td align="center"><code>\e\e[18;5~</code></td>
|
||
<td align="center"><code>\e\e[18;6~</code></td>
|
||
</tr>
|
||
<tr>
|
||
<td align="center">F8</td>
|
||
<td align="center"><code>\e[19~</code></td>
|
||
<td align="center"><code>\e[19;2~</code></td>
|
||
<td align="center"><code>\e[19;5~</code></td>
|
||
<td align="center"><code>\e[19;6~</code></td>
|
||
<td align="center"><code>\e\e[19~</code></td>
|
||
<td align="center"><code>\e\e[19;2~</code></td>
|
||
<td align="center"><code>\e\e[19;5~</code></td>
|
||
<td align="center"><code>\e\e[19;6~</code></td>
|
||
</tr>
|
||
<tr>
|
||
<td align="center">F9</td>
|
||
<td align="center"><code>\e[20~</code></td>
|
||
<td align="center"><code>\e[20;2~</code></td>
|
||
<td align="center"><code>\e[20;5~</code></td>
|
||
<td align="center"><code>\e[20;6~</code></td>
|
||
<td align="center"><code>\e\e[20~</code></td>
|
||
<td align="center"><code>\e\e[20;2~</code></td>
|
||
<td align="center"><code>\e\e[20;5~</code></td>
|
||
<td align="center"><code>\e\e[20;6~</code></td>
|
||
</tr>
|
||
<tr>
|
||
<td align="center">F10</td>
|
||
<td align="center"><code>\e[21~</code></td>
|
||
<td align="center"><code>\e[21;2~</code></td>
|
||
<td align="center"><code>\e[21;5~</code></td>
|
||
<td align="center"><code>\e[21;6~</code></td>
|
||
<td align="center"><code>\e\e[21~</code></td>
|
||
<td align="center"><code>\e\e[21;2~</code></td>
|
||
<td align="center"><code>\e\e[21;5~</code></td>
|
||
<td align="center"><code>\e\e[21;6~</code></td>
|
||
</tr>
|
||
<tr>
|
||
<td align="center">F11</td>
|
||
<td align="center"><code>\e[23~</code></td>
|
||
<td align="center"><code>\e[23;2~</code></td>
|
||
<td align="center"><code>\e[23;5~</code></td>
|
||
<td align="center"><code>\e[23;6~</code></td>
|
||
<td align="center"><code>\e\e[23~</code></td>
|
||
<td align="center"><code>\e\e[23;2~</code></td>
|
||
<td align="center"><code>\e\e[23;5~</code></td>
|
||
<td align="center"><code>\e\e[23;6~</code></td>
|
||
</tr>
|
||
<tr>
|
||
<td align="center">F12</td>
|
||
<td align="center"><code>\e[24~</code></td>
|
||
<td align="center"><code>\e[24;2~</code></td>
|
||
<td align="center"><code>\e[24;5~</code></td>
|
||
<td align="center"><code>\e[24;6~</code></td>
|
||
<td align="center"><code>\e\e[24~</code></td>
|
||
<td align="center"><code>\e\e[24;2~</code></td>
|
||
<td align="center"><code>\e\e[24;5~</code></td>
|
||
<td align="center"><code>\e\e[24;6~</code></td>
|
||
</tr>
|
||
</tbody></table>
|
||
<p>When the <code>terminal.differentiate_keys</code> setting is enabled then the following key bindings are also available:</p>
|
||
<table>
|
||
<thead>
|
||
<tr>
|
||
<th align="center"></th>
|
||
<th align="center">Ctrl</th>
|
||
<th align="center">Ctrl+Shift</th>
|
||
<th align="center">Alt</th>
|
||
<th align="center">Alt+Shift</th>
|
||
<th align="center">Alt+Ctrl</th>
|
||
<th align="center">Alt+Ctrl+Shift</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody><tr>
|
||
<td align="center">H</td>
|
||
<td align="center"><code>\e[27;5;72~</code></td>
|
||
<td align="center"><code>\e[27;6;72~</code></td>
|
||
<td align="center"><code>\eh</code></td>
|
||
<td align="center"><code>\eH</code></td>
|
||
<td align="center"><code>\e[27;7;72~</code></td>
|
||
<td align="center"><code>\e[27;8;72~</code></td>
|
||
</tr>
|
||
<tr>
|
||
<td align="center">I</td>
|
||
<td align="center"><code>\e[27;5;73~</code></td>
|
||
<td align="center"><code>\e[27;6;73~</code></td>
|
||
<td align="center"><code>\ei</code></td>
|
||
<td align="center"><code>\eI</code></td>
|
||
<td align="center"><code>\e[27;7;73~</code></td>
|
||
<td align="center"><code>\e[27;8;73~</code></td>
|
||
</tr>
|
||
<tr>
|
||
<td align="center">M</td>
|
||
<td align="center"><code>\e[27;5;77~</code></td>
|
||
<td align="center"><code>\e[27;6;77~</code></td>
|
||
<td align="center"><code>\em</code></td>
|
||
<td align="center"><code>\eM</code></td>
|
||
<td align="center"><code>\e[27;7;77~</code></td>
|
||
<td align="center"><code>\e[27;8;77~</code></td>
|
||
</tr>
|
||
<tr>
|
||
<td align="center">[</td>
|
||
<td align="center"><code>\e[27;5;219~</code></td>
|
||
<td align="center"><code>\e[27;6;219~</code></td>
|
||
<td align="center"><code>\e[27;3;219~</code></td>
|
||
<td align="center"><code>\e[27;4;219~</code></td>
|
||
<td align="center"><code>\e[27;7;219~</code></td>
|
||
<td align="center"><code>\e[27;8;219~</code></td>
|
||
</tr>
|
||
</tbody></table>
|
||
<a name="luakeybindings"/>
|
||
|
||
<h3 id="lua-key-bindings">Lua Key Bindings</h3>
|
||
<p>You can bind a key to a Lua function by binding it to a macro that begins with "luafunc:". Clink will invoke the named Lua function when the key binding is input. Function names can include periods (such as <code>foo.bar</code>) but cannot include any other punctuation.</p>
|
||
<p>The Lua function receives a <a href="#rl_buffer">rl_buffer</a> argument that gives it access to the input buffer.</p>
|
||
<p>Lua functions can print output, but should first call <a href="#rl_buffer:beginoutput">rl_buffer:beginoutput</a> so that the output doesn't overwrite the displayed input line.</p>
|
||
<p>Example of a Lua function key binding in a .inputrc file:</p>
|
||
<pre><code class="plaintext"><span class="hljs-string">M-C-y</span>: <span class="hljs-string">"luafunc:insert_date"</span>
|
||
<span class="hljs-string">M-C-z</span>: <span class="hljs-string">"luafunc:print_date"</span>
|
||
</code></pre>
|
||
|
||
<p>Example functions to go with that:</p>
|
||
<pre><code class="language-lua">function insert_date(rl_buffer)
|
||
rl_buffer:insert(os.date("%x %X"))
|
||
end
|
||
|
||
function print_date(rl_buffer)
|
||
rl_buffer:beginoutput()
|
||
print(os.date("%A %B %d, %Y %I:%M %p"))
|
||
end
|
||
</code></pre>
|
||
<h2 id="saved-command-history">Saved Command History</h2>
|
||
<p>Clink has a list of commands from the current session, and it can be saved and loaded across sessions.</p>
|
||
<p>A line won't be added to history if either of the following are true:</p>
|
||
<ul>
|
||
<li>The first word in the line matches one of the words in the <code>history.dont_add_to_history_cmds</code> setting.</li>
|
||
<li>The line begins with a space character.</li>
|
||
</ul>
|
||
<p>To prevent doskey alias expansion while still adding the line to history, you can start the line with a semicolon.</p>
|
||
<table>
|
||
<thead>
|
||
<tr>
|
||
<th>Line</th>
|
||
<th>Description</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody><tr>
|
||
<td><code>somecmd</code></td>
|
||
<td>Expands doskey alias and adds to history.</td>
|
||
</tr>
|
||
<tr>
|
||
<td><code> somecmd</code></td>
|
||
<td>Doesn't expand doskey alias and doesn't add to history.</td>
|
||
</tr>
|
||
<tr>
|
||
<td><code>;somecmd</code></td>
|
||
<td>Doesn't expand doskey alias but does add to history.</td>
|
||
</tr>
|
||
</tbody></table>
|
||
<h3 id="the-master-history-file">The master history file</h3>
|
||
<p>When the <code>history.saved</code> setting is enabled, then the command history is loaded and saved as follows (or when the setting is disabled, then it isn't saved between sessions).</p>
|
||
<p>Every time a new input line starts, Clink reloads the master history list and prunes it not to exceed the <code>history.max_lines</code> setting.</p>
|
||
<p>For performance reasons, deleting a history line marks the line as deleted without rewriting the history file. When the number of deleted lines gets too large (exceeding the max lines or 200, whichever is larger) then the history file is compacted: the file is rewritten with the deleted lines removed.</p>
|
||
<p>You can force the history file to be compacted regardless of the number of deleted lines by running <code>history compact</code>.</p>
|
||
<h3 id="shared-command-history">Shared command history</h3>
|
||
<p>When the <code>history.shared</code> setting is enabled, then all instances of Clink update the master history file and reload it every time a new input line starts. This gives the effect that all instances of Clink share the same history -- a command entered in one instance will appear in other instances' history the next time they start an input line.</p>
|
||
<p>When the setting is disabled, then each instance of Clink loads the master file but doesn't append its own history back to the master file until after it exits, giving the effect that once an instance starts its history is isolated from other instances' history.</p>
|
||
<h3 id="multiple-master-history-files">Multiple master history files</h3>
|
||
<p>Normally Clink saves a single saved master history list. All instances of Clink load and save the same master history list.</p>
|
||
<p>It's also possible to make one or more instances of Clink use a different saved master history list by setting the <code>%CLINK_HISTORY_LABEL%</code> environment variable. This can be up to 32 alphanumeric characters, and is appended to the master history file name. Changing the <code>%CLINK_HISTORY_LABEL%</code> environment variable takes effect at the next input line.</p>
|
||
<h1 id="sample-scripts">Sample Scripts</h1>
|
||
<p>Here are a few samples of what can be done with Clink.</p>
|
||
<h3 id="clink-completions">clink-completions</h3>
|
||
<p>The <a href="https://github.com/vladimir-kotikov/clink-completions">clink-completions</a> collection of scripts has a bunch of argument matchers and completion generators for things like git, mercurial, npm, and more.</p>
|
||
<h3 id="cmder-powerline-prompt">cmder-powerline-prompt</h3>
|
||
<p>The <a href="https://github.com/chrisant996/cmder-powerline-prompt">cmder-powerline-prompt</a> collection of scripts provides a Powerline-like prompt for Clink. It's extensible so you can add your own segments, and some configuration of built-in segments is also available.</p>
|
||
<h3 id="oh-my-posh">oh-my-posh</h3>
|
||
<p>The <a href="https://github.com/JanDeDobbeleer/oh-my-posh3">oh-my-posh</a> program can generate fancy prompts. Refer to its documentation for how to configure it.</p>
|
||
<p>Integrating oh-my-posh with Clink is easy: just save the following text to an <code>oh-my-posh.lua</code> file in your Clink scripts directory (run <code>clink info</code> to find that), and make sure the oh-my-posh.exe program is in a directory listed in the %PATH% environment variable. (Or edit the script below to provide a fully qualified path to the oh-my-posh.exe program.)</p>
|
||
<pre><code class="language-lua">-- oh-my-posh.lua
|
||
local ohmyposh_prompt = clink.promptfilter(1)
|
||
function ohmyposh_prompt:filter(prompt)
|
||
prompt = io.popen("oh-my-posh.exe"):read("*a")
|
||
return prompt, false
|
||
end
|
||
</code></pre>
|
||
<h3 id="zlua">z.lua</h3>
|
||
<p>The <a href="https://github.com/skywind3000/z.lua">z.lua</a> tool is a faster way to navigate directories, and it integrates with Clink.</p>
|
||
<h1 id="troubleshooting-tips">Troubleshooting Tips</h1>
|
||
<p>If something seems to malfunction, here are some things to try that often help track down what's going wrong:</p>
|
||
<ul>
|
||
<li>Check if anti-malware software blocked Clink from injecting. Consider adding an exclusion for Clink.</li>
|
||
<li>Check <code>clink info</code>. E.g. does the state dir look right, do the script paths look right, do the inputrc files look right?</li>
|
||
<li>Check <code>clink set</code>. E.g. do the settings look right?</li>
|
||
<li>Check the <code>clink.log</code> file for clues (its location is reported by <code>clink info</code>).</li>
|
||
</ul>
|
||
<p>When <a href="https://github.com/chrisant996/clink/issues">reporting an issue</a>, please include the following which answer a bunch of commonly relevant questions and saves time:</p>
|
||
<ul>
|
||
<li>Please describe what was expected to happen.</li>
|
||
<li>Please describe what actually happened.</li>
|
||
<li>Please include the output from <code>clink info</code> and <code>clink set</code>.</li>
|
||
<li>Please include the <code>clink.log</code> file (the location is reported by <code>clink info</code>).</li>
|
||
</ul>
|
||
</div>
|
||
<h1 id="lua-api">Lua API Reference</h1>
|
||
This section describes the Clink Lua API extensions.
|
||
Also see <a href="https://www.lua.org/docs.html">Lua Documentation</a> for more information about the Lua programming language.
|
||
<div class="section" id="api">
|
||
<div class="group"><h5 class="group_name"><a name="_argmatcher">_argmatcher</a></h5><div class="function"><div class="header"> <div class="name"><a name="_argmatcher:addarg">_argmatcher:addarg</a></div> <div class="signature">( <span class="arg_name">choices...</span>:string|table ) : self</div></div><div class="body"><p class="desc">This adds argument matches. Arguments can be a string, a string linked to another parser by the concatenation operator, a table of arguments, or a function that returns a table of arguments. See <a href="#argumentcompletion">Argument Completion</a> for more information.</p><pre class="language-lua"><code>local my_parser = clink.argmatcher("git")
|
||
:addarg("add", "status", "commit", "checkout")</code></pre></div></div><hr/>
|
||
<div class="function"><div class="header"> <div class="name"><a name="_argmatcher:addflags">_argmatcher:addflags</a></div> <div class="signature">( <span class="arg_name">flags...</span>:string ) : self</div></div><div class="body"><p class="desc">This adds flag matches. Flags are separate from arguments: When listing possible completions for an empty word, only arguments are listed. But when the word being completed starts with the first character of any of the flags, then only flags are listed. See <a href="#argumentcompletion">Argument Completion</a> for more information.</p><pre class="language-lua"><code>local my_parser = clink.argmatcher("git")
|
||
:addarg({ "add", "status", "commit", "checkout" })
|
||
:addflags("-a", "-g", "-p", "--help")</code></pre></div></div><hr/>
|
||
<div class="function"><div class="header"> <div class="name"><a name="_argmatcher:loop">_argmatcher:loop</a></div> <div class="signature">( [<span class="arg_name">index</span>:integer] ) : self</div></div><div class="body"><p class="desc">This makes the parser loop back to argument position <span class="arg">index</span> when it runs out of positional sets of arguments (if <span class="arg">index</span> is omitted it loops back to argument position 1).</p><pre class="language-lua"><code>clink.argmatcher("xyzzy")
|
||
:addarg("zero", "cero") -- first arg can be zero or cero
|
||
:addarg("one", "uno") -- second arg can be one or uno
|
||
:addarg("two", "dos") -- third arg can be two or dos
|
||
:loop(2) -- fourth arg loops back to position 2, for one or uno, and so on</code></pre></div></div><hr/>
|
||
<div class="function"><div class="header"> <div class="name"><a name="_argmatcher:nofiles">_argmatcher:nofiles</a></div> <div class="signature">() : self</div></div><div class="body"><p class="desc">This makes the parser prevent invoking <a href="#matchgenerators">match generators</a>. You can use it to "dead end" a parser and suggest no completions.</p></div></div><hr/>
|
||
<div class="function"><div class="header"> <div class="name"><a name="_argmatcher:setclassifier">_argmatcher:setclassifier</a></div> <div class="signature">( <span class="arg_name">func</span>:function ) : self</div></div><div class="body"><p class="desc">This registers a function that gets called for each word the argmatcher handles, to classify the word as part of coloring the input text. See <a href="#classifywords">Coloring The Input Text</a> for more information.</p></div></div><hr/>
|
||
<div class="function"><div class="header"> <div class="name"><a name="_argmatcher:setflagprefix">_argmatcher:setflagprefix</a></div> <div class="signature">( [<span class="arg_name">prefixes...</span>:string] ) : self</div></div><div class="body deprecated"><p class="desc"><strong>Deprecated; don't use this.</strong> See <a href="#_argmatcher:addflags">_argmatcher:addflags</a> for more information.</p><p class="desc">This overrides the default flag prefix (<code>-</code>). The flag prefixes are used to switch between matching arguments versus matching flags. When listing possible completions for an empty word (e.g. <code>command _</code> where the cursor is at the <code>_</code>), only arguments are listed. And only flags are listed when the word starts with one of the flag prefixes. Each flag prefix must be a single character, but there can be multiple prefixes.</p><p class="desc"> This is no longer needed because <code>:addflags()</code> does it automatically.</p><pre class="language-lua"><code>local my_parser = clink.argmatcher()
|
||
:setflagprefix("-", "/", "+")
|
||
:addflags("--help", "/?", "+mode")</code></pre></div></div><hr/>
|
||
</div><div class="group"><h5 class="group_name"><a name="builder">builder</a></h5><div class="function"><div class="header"> <div class="name"><a name="builder:addmatch">builder:addmatch</a></div> <div class="signature">( <span class="arg_name">match</span>:string|table, [<span class="arg_name">type</span>:string] ) : boolean</div></div><div class="body"><p class="desc">Adds a match. If <span class="arg">match</span> is a string, it's added as a match and <span class="arg">type</span> is the optional match type.</p><p class="desc"> Or <span class="arg">match</span> can be a table with the following scheme: <span class="tablescheme">{ match:string, [type:string] }</span>. If a table element is missing the type field, then the <span class="arg">type</span> argument is used for that element.</p><p class="desc"> If the <span class="arg">type</span> argument is omitted, "none" is assumed.</p><p class="desc"> The match type can affect how the match is inserted, displayed, and colored:</p><p class="desc"> <table> <tr><th>Type</th><th>Description</th></tr> <tr><td>"word"</td><td>Shows the whole word even if it contains slashes.</td></tr> <tr><td>"arg"</td><td>Avoids appending a space if the match ends with a colon or equal sign.</td></tr> <tr><td>"command"</td><td>Displays the match using <a href="#color_cmd">color.cmd</a>.</td></tr> <tr><td>"alias"</td><td>Displays the match using <a href="#color_doskey">color.doskey</a>.</td></tr> <tr><td>"file"</td><td>Shows only the last path component, with appropriate file coloring.</td></tr> <tr><td>"dir"</td><td>Shows only the last path component and adds a trailing path separator, with appropriate directory coloring.</td></tr> <tr><td>"link"</td><td>Shows only the last path component, with appropriate symlink coloring. <em>Not supported yet.</em></td></tr> <tr><td>"none"</td><td>For backward compatibility the match is treated like "file", unless it ends with a path separator in which case it's treated like "dir".</td></tr> </table></p><p class="desc"> <table> <tr><th>Modifier</th><th>Description</th></tr> <tr><td>"hidden"</td><td>This can be combined with "file" or "dir" to use <a href="#color_hidden">color.hidden</a> (e.g. "file,hidden").</td></tr> <tr><td>"readonly"</td><td>This can be combined with "file" or "dir" to use <a href="#color_readonly">color.readonly</a> (e.g. "file,readonly").</td></tr> </table></p><p class="desc"> See <a href="#completioncolors">Completion Colors</a> and <a href="#colorsettings">Color Settings</a> for more information about colors.</p><pre class="language-lua"><code>builder:addmatch("hello") -- type is "none"
|
||
builder:addmatch("some_word", "word")
|
||
builder:addmatch("/flag", "arg")
|
||
builder:addmatch("abbrev", "alias")
|
||
builder:addmatch({ match="foo.cpp", type="file" })
|
||
builder:addmatch({ match="bar", type="dir" })
|
||
builder:addmatch({ match=".git", type="dir hidden" })</code></pre></div></div><hr/>
|
||
<div class="function"><div class="header"> <div class="name"><a name="builder:addmatches">builder:addmatches</a></div> <div class="signature">( <span class="arg_name">matches</span>:table, [<span class="arg_name">type</span>:string] ) : integer, boolean</div></div><div class="body"><p class="desc">This is the equivalent of calling <a href="#builder:addmatch">builder:addmatch()</a> in a for-loop. Returns the number of matches added and a boolean indicating if all matches were added successfully.</p><p class="desc"> <span class="arg">matches</span> can be a table of match strings, or a table of tables describing the matches.<br/> <span class="arg">type</span> is used as the type when a match doesn't explicitly include a type, and is "none" if omitted.</p><pre class="language-lua"><code>builder:addmatches({"abc", "def"}) -- Adds two matches of type "none"
|
||
builder:addmatches({"abc", "def"}, "file") -- Adds two matches of type "file"
|
||
builder:addmatches({
|
||
-- Same table scheme per entry here as in builder:addmatch()
|
||
{ match="remote/origin/master", type="word" },
|
||
{ match="remote/origin/topic", type="word" }
|
||
})</code></pre></div></div><hr/>
|
||
<div class="function"><div class="header"> <div class="name"><a name="builder:setappendcharacter">builder:setappendcharacter</a></div> <div class="signature">( [<span class="arg_name">append</span>:string] ) : nil</div></div><div class="body"><p class="desc">Sets character to append after matches. For example the <code>set</code> match generator uses this to append "=" when completing matches, so that completing <code>set USER</code> becomes <code>set USERDOMAIN=</code> (rather than <code>set USERDOMAIN </code>).</p></div></div><hr/>
|
||
<div class="function"><div class="header"> <div class="name"><a name="builder:setsuppressappend">builder:setsuppressappend</a></div> <div class="signature">( [<span class="arg_name">state</span>:boolean] ) : nil</div></div><div class="body"><p class="desc">Sets whether to suppress appending anything after the match except a possible closing quote. For example the env var match generator uses this.</p></div></div><hr/>
|
||
<div class="function"><div class="header"> <div class="name"><a name="builder:setsuppressquoting">builder:setsuppressquoting</a></div> <div class="signature">( [<span class="arg_name">state</span>:integer] ) : nil</div></div><div class="body"><p class="desc">Sets whether to suppress quoting for the matches. Set to 0 for normal quoting, or 1 to suppress quoting, or 2 to suppress end quotes. For example the env var match generator sets this to 1 to overcome the quoting that would normally happen for "%" characters in filenames.</p></div></div><hr/>
|
||
</div><div class="group"><h5 class="group_name"><a name="clink">clink</a></h5><div class="function"><div class="header"> <div class="name"><a name="clink.add_match">clink.add_match</a></div> <div class="signature">( <span class="arg_name">match</span>:string ) : nil</div></div><div class="body deprecated"><p class="desc"><strong>Deprecated; don't use this.</strong> See <a href="#builder:addmatch">builder:addmatch</a> for more information.</p><p class="desc">This is a shim that lets clink.register_match_generator continue to work for now, despite being obsolete.</p></div></div><hr/>
|
||
<div class="function"><div class="header"> <div class="name"><a name="clink.argmatcher">clink.argmatcher</a></div> <div class="signature">( [<span class="arg_name">priority</span>:integer], <span class="arg_name">commands...</span>:string ) : <a href="#_argmatcher">_argmatcher</a></div></div><div class="body"><p class="desc">Creates and returns a new argument matcher parser object. Use <a href="#_argmatcher:addarg">:addarg()</a> and etc to add arguments, flags, other parsers, and more. See <a href="#argumentcompletion">Argument Completion</a> for more information.</p><p class="desc"> If one <span class="arg">command</span> is provided and an argument matcher parser object is already associated with the command, this returns the existing parser rather than creating a new parser. Using :addarg() starts at arg position 1, making it possible to merge new args and etc into the existing parser.</p></div></div><hr/>
|
||
<div class="function"><div class="header"> <div class="name"><a name="clink.classifier">clink.classifier</a></div> <div class="signature">( [<span class="arg_name">priority</span>:integer] ) : table</div></div><div class="body"><p class="desc">Creates and returns a new word classifier object. Define on the object a <code>classify()</code> function which gets called in increasing <span class="arg">priority</span> order (low values to high values) when classifying words for coloring the input. See <a href="#classifywords">Coloring The Input Text</a> for more information.</p></div></div><hr/>
|
||
<div class="function"><div class="header"> <div class="name"><a name="clink.dirmatches">clink.dirmatches</a></div> <div class="signature">( <span class="arg_name">word</span>:string ) : table</div></div><div class="body"><p class="desc">You can use this function in an argmatcher to supply directory matches. This automatically handles Readline tilde completion.</p><pre class="language-lua"><code>-- Make "cd" generate directory matches (no files).
|
||
clink.argmatcher("cd")
|
||
:addflags("/d")
|
||
:addarg({ clink.dirmatches })</code></pre></div></div><hr/>
|
||
<div class="function"><div class="header"> <div class="name"><a name="clink.filematches">clink.filematches</a></div> <div class="signature">( <span class="arg_name">word</span>:string ) : table</div></div><div class="body"><p class="desc">You can use this function in an argmatcher to supply file matches. This automatically handles Readline tilde completion.</p><p class="desc"> Argmatchers default to matching files, so it's unusual to need this function. However, some exceptions are when a flag needs to accept file matches but other flags and arguments don't, or when matches need to include more than files.</p><pre class="language-lua"><code>-- Make "foo --file" generate file matches, but other flags and args don't.
|
||
-- And the third argument can be a file or $stdin or $stdout.
|
||
clink.argmatcher("foo")
|
||
:addflags(
|
||
"--help",
|
||
"--file"..clink.argmatcher():addarg({ clink.filematches })
|
||
)
|
||
:addarg({ "one", "won" })
|
||
:addarg({ "two", "too" })
|
||
:addarg({ clink.filematches, "$stdin", "$stdout" })</code></pre></div></div><hr/>
|
||
<div class="function"><div class="header"> <div class="name"><a name="clink.generator">clink.generator</a></div> <div class="signature">( [<span class="arg_name">priority</span>:integer] ) : table</div></div><div class="body"><p class="desc">Creates and returns a new match generator object. Define on the object a <code>generate()</code> function which gets called in increasing <span class="arg">priority</span> order (low values to high values) when generating matches for completion. See <a href="#matchgenerators">Match Generators</a> for more information.</p></div></div><hr/>
|
||
<div class="function"><div class="header"> <div class="name"><a name="clink.getansihost">clink.getansihost</a></div> <div class="signature">() : string</div></div><div class="body"><p class="desc">Returns a string indicating who Clink thinks will currently handle ANSI escape codes. This can change based on the <code>terminal.emulation</code> setting. This always returns <code>"unknown"</code> until the first edit prompt (see <a href="#clink.onbeginedit">clink.onbeginedit()</a>).</p><p class="desc"> This can be useful in choosing what kind of ANSI escape codes to use, but it is a best guess and is not necessarily 100% reliable.</p><p class="desc"> <table> <tr><th>Return</th><th>Description</th></tr> <tr><td>"unknown"</td><td>Clink doesn't know.</td></tr> <tr><td>"clink"</td><td>Clink is emulating ANSI support. 256 color and 24 bit color escape codes are mapped to the nearest of the 16 basic colors.</td></tr> <tr><td>"conemu"</td><td>Clink thinks ANSI escape codes will be handled by ConEmu.</td></tr> <tr><td>"ansicon"</td><td>Clink thinks ANSI escape codes will be handled by ANSICON.</td></tr> <tr><td>"winterminal"</td><td>Clink thinks ANSI escape codes will be handled by Windows Terminal.</td></tr> <tr><td>"winconsole"</td><td>Clink thinks ANSI escape codes will be handled by the default console support in Windows, but Clink detected a terminal replacement that won't support 256 color or 24 bit color.</td></tr> <tr><td>"winconsolev2"</td><td>Clink thinks ANSI escape codes will be handled by the default console support in Windows, or it might be handled by a terminal replacement that Clink wasn't able to detect.</td></tr> </table></p></div></div><hr/>
|
||
<div class="function"><div class="header"> <div class="name"><a name="clink.getsession">clink.getsession</a></div> <div class="signature">() : string</div></div><div class="body"><p class="desc">Returns the current Clink session id.</p><p class="desc"> This is needed when using <code>io.popen()</code> (or similar functions) to invoke <code>clink history</code> or <code>clink info</code> while Clink is installed for autorun. The popen API spawns a new CMD.exe, which gets a new Clink instance injected, so the history or info command will use the new session unless explicitly directed to use the calling session.</p><pre class="language-lua"><code>local c = os.getalias("clink")
|
||
local r = io.popen(c.." --session "..clink.getsession().." history")</code></pre></div></div><hr/>
|
||
<div class="function"><div class="header"> <div class="name"><a name="clink.is_match">clink.is_match</a></div> <div class="signature">( <span class="arg_name">needle</span>:string, <span class="arg_name">candidate</span>:string ) : boolean</div></div><div class="body deprecated"><p class="desc"><strong>Deprecated; don't use this.</strong> See <a href="#clink.generator">clink.generator</a> for more information.</p><p class="desc">This returns true if <span class="arg">needle</span> is a prefix of <span class="arg">candidate</span> with a case insensitive comparison.</p><p class="desc"> Normally in Clink v1.x and higher the <span class="arg">needle</span> will be an empty string because the generators are no longer responsible for filtering matches. The match pipeline itself handles that internally now.</p></div></div><hr/>
|
||
<div class="function"><div class="header"> <div class="name"><a name="clink.lower">clink.lower</a></div> <div class="signature">( <span class="arg_name">text</span>:string ) : string</div></div><div class="body"><p class="desc">This API correctly converts UTF8 strings to lowercase, with international linguistic awareness.</p><pre class="language-lua"><code>clink.lower("Hello World") -- returns "hello world"</code></pre></div></div><hr/>
|
||
<div class="function"><div class="header"> <div class="name"><a name="clink.match_display_filter">clink.match_display_filter</a></div> <div class="signature">function variable</div></div><div class="body deprecated"><p class="desc"><strong>Deprecated; don't use this.</strong> See <a href="#clink.ondisplaymatches">clink.ondisplaymatches</a> for more information.</p><p class="desc">A match generator can set this varible to a filter function that is called before displaying matches. It is reset every time match generation is invoked. The filter function receives table argument containing the matches that are going to be displayed, and it returns a table filtered as required by the match generator.</p><p class="desc"> See <a href="#filteringthematchdisplay">Filtering the Match Display</a> for more information.</p></div></div><hr/>
|
||
<div class="function"><div class="header"> <div class="name"><a name="clink.match_display_filter">clink.match_display_filter</a></div> <div class="signature">function variable</div></div><div class="body deprecated"><p class="desc"><strong>Deprecated; don't use this.</strong> See <a href="#builder:addmatch">builder:addmatch</a> for more information.</p><p class="desc">This is no longer used.</p><pre class="language-lua"><code>clink.match_display_filter = function(matches)
|
||
-- Transform matches.
|
||
return matches
|
||
end</code></pre></div></div><hr/>
|
||
<div class="function"><div class="header"> <div class="name"><a name="clink.matches_are_files">clink.matches_are_files</a></div> <div class="signature">( [<span class="arg_name">files</span>:boolean] ) : nil</div></div><div class="body deprecated"><p class="desc"><strong>Deprecated; don't use this.</strong> See <a href="#builder:addmatch">builder:addmatch</a> for more information.</p><p class="desc">This is no longer needed, because now it's inferred from the match type when adding matches.</p></div></div><hr/>
|
||
<div class="function"><div class="header"> <div class="name"><a name="clink.onbeginedit">clink.onbeginedit</a></div> <div class="signature">( <span class="arg_name">func</span>:function ) : nil</div></div><div class="body"><p class="desc">Registers <span class="arg">func</span> to be called when Clink's edit prompt is activated. The function receives no arguments and has no return values.</p></div></div><hr/>
|
||
<div class="function"><div class="header"> <div class="name"><a name="clink.ondisplaymatches">clink.ondisplaymatches</a></div> <div class="signature">( <span class="arg_name">func</span>:function ) : nil</div></div><div class="body"><p class="desc">Registers <span class="arg">func</span> to be called when Clink is about to display matches. See <a href="#filteringthematchdisplay">Filtering the Match Display</a> for more information.</p><pre class="language-lua"><code>local function my_filter(matches, popup)
|
||
local new_matches = {}
|
||
for _,m in ipairs(matches) do
|
||
if m.match:find("[0-9]") then
|
||
-- Ignore matches with one or more digits.
|
||
else
|
||
-- Keep the match, and also add * prefix to directory matches.
|
||
if m.type:find("^dir") then
|
||
m.display = "*"..m.match
|
||
end
|
||
table.insert(new_matches, m)
|
||
end
|
||
end
|
||
return new_matches
|
||
end
|
||
|
||
function my_match_generator:generate(line_state, match_builder)
|
||
...
|
||
clink.ondisplaymatches(my_filter)
|
||
end</code></pre></div></div><hr/>
|
||
<div class="function"><div class="header"> <div class="name"><a name="clink.onendedit">clink.onendedit</a></div> <div class="signature">( <span class="arg_name">func</span>:function ) : nil</div></div><div class="body"><p class="desc">Registers <span class="arg">func</span> to be called when Clink's edit prompt ends. The function receives a string argument containing the input text from the edit prompt. The function returns up to two values. If the first is not nil then it's a string that replaces the edit prompt text. If the second is not nil and is false then it stops further onendedit handlers from running.</p><p class="desc"> <strong>Note:</strong> Be very careful if you replace the text; this has the potential to interfere with or even ruin the user's ability to enter command lines for CMD to process.</p></div></div><hr/>
|
||
<div class="function"><div class="header"> <div class="name"><a name="clink.onfiltermatches">clink.onfiltermatches</a></div> <div class="signature">( <span class="arg_name">func</span>:function ) : nil</div></div><div class="body"><p class="desc">Registers <span class="arg">func</span> to be called after Clink generates matches for completion. See <a href="#filteringmatchcompletions"> Filtering Match Completions</a> for more information.</p></div></div><hr/>
|
||
<div class="function"><div class="header"> <div class="name"><a name="clink.oninject">clink.oninject</a></div> <div class="signature">( <span class="arg_name">func</span>:function ) : nil</div></div><div class="body"><p class="desc">Registers <span class="arg">func</span> to be called when Clink is injected into a CMD process. The function is called only once per session.</p></div></div><hr/>
|
||
<div class="function"><div class="header"> <div class="name"><a name="clink.promptfilter">clink.promptfilter</a></div> <div class="signature">( [<span class="arg_name">priority</span>:integer] ) : table</div></div><div class="body"><p class="desc">Creates and returns a new promptfilter object that is applied in increasing <span class="arg">priority</span> order (low values to high values). Define on the object a <code>filter()</code> function that takes a string argument which contains the filtered prompt so far. The function can return nil to have no effect, or can return a new prompt string. It can optionally stop further prompt filtering by also returning false. See <a href="#customisingtheprompt">Customising The Prompt</a> for more information.</p><pre class="language-lua"><code>local foo_prompt = clink.promptfilter(80)
|
||
function foo_prompt:filter(prompt)
|
||
-- Insert the date at the beginning of the prompt.
|
||
return os.date("%a %H:%M").." "..prompt
|
||
end</code></pre></div></div><hr/>
|
||
<div class="function"><div class="header"> <div class="name"><a name="clink.register_match_generator">clink.register_match_generator</a></div> <div class="signature">( <span class="arg_name">func</span>:function, <span class="arg_name">priority</span>:integer ) : nil</div></div><div class="body deprecated"><p class="desc"><strong>Deprecated; don't use this.</strong> See <a href="#clink.generator">clink.generator</a> for more information.</p><p class="desc">Registers a generator function for producing matches. This behaves similarly to v0.4.8, but not identically. The Clink schema has changed significantly enough that there is no direct 1:1 translation; generators are called at a different time than before and have access to more information than before.</p><pre class="language-lua"><code>-- Deprecated form:
|
||
local function match_generator_func(text, first, last)
|
||
-- `text` is the word text.
|
||
-- `first` is the index of the beginning of the end word.
|
||
-- `last` is the index of the end of the end word.
|
||
-- `clink.add_match()` is used to add matches.
|
||
-- return true if handled, or false to let another generator try.
|
||
end
|
||
clink.register_match_generator(match_generator_func, 10)
|
||
|
||
-- Replace with new form:
|
||
local g = clink.generator(10)
|
||
function g:generate(line_state, match_builder)
|
||
-- `line_state` is a <a href="#line">line</a> object.
|
||
-- `match_builder:<a href="#builder:addmatch">addmatch</a>()` is used to add matches.
|
||
-- return true if handled, or false to let another generator try.
|
||
end</code></pre></div></div><hr/>
|
||
<div class="function"><div class="header"> <div class="name"><a name="clink.slash_translation">clink.slash_translation</a></div> <div class="signature">( <span class="arg_name">type</span>:integer ) : nil</div></div><div class="body deprecated"><p class="desc"><strong>Deprecated; don't use this.</strong> See <a href="#clink.translateslashes">clink.translateslashes</a> for more information.</p><p class="desc">Controls how Clink will translate the path separating slashes for the current path being completed. Values for <span class="arg">type</span> are;</br> -1 - no translation</br> 0 - to backslashes</br> 1 - to forward slashes</p></div></div><hr/>
|
||
<div class="function"><div class="header"> <div class="name"><a name="clink.translateslashes">clink.translateslashes</a></div> <div class="signature">( [<span class="arg_name">mode</span>:integer] ) : integer</div></div><div class="body"><p class="desc">This overrides how Clink translates slashes in completion matches, which is normally determined by the <code>match.translate_slashes</code> setting.</p><p class="desc"> This is reset every time match generation is invoked, so use a generator to set this.</p><p class="desc"> The <span class="arg">mode</span> specifies how to translate slashes when generators add matches: <table> <tr><th>Mode</th><th>Description</th></tr> <tr><td><code>0</code></td><td>No translation.</td></tr> <tr><td><code>1</code></td><td>Translate using the system path separator (backslash on Windows).</td></tr> <tr><td><code>2</code></td><td>Translate to slashes (<code>/</code>).</td></tr> <tr><td><code>3</code></td><td>Translate to backslashes (<code>\</code>).</td></tr> </table></p><p class="desc"> If <span class="arg">mode</span> is omitted, then the function returns the current slash translation mode without changing it.</p><p class="desc"> Note: Clink always generates file matches using the system path separator (backslash on Windows), regardless what path separator may have been typed as input. Setting this to <code>0</code> does not disable normalizing typed input paths when invoking completion; it only disables translating slashes in custom generators.</p><pre class="language-lua"><code>-- This example affects all match generators, by using priority -1 to
|
||
-- run first and returning false to let generators continue.
|
||
-- To instead affect only one generator, call clink.translateslashes()
|
||
-- in its :generate() function and return true.
|
||
local force_slashes = clink.generator(-1)
|
||
function force_slashes:generate()
|
||
clink.translateslashes(2) -- Convert to slashes.
|
||
return false -- Allow generators to continue.
|
||
end</code></pre></div></div><hr/>
|
||
<div class="function"><div class="header"> <div class="name"><a name="clink.upper">clink.upper</a></div> <div class="signature">( <span class="arg_name">text</span>:string ) : string</div></div><div class="body"><p class="desc">This API correctly converts UTF8 strings to uppercase, with international linguistic awareness.</p><pre class="language-lua"><code>clink.upper("Hello World") -- returns "HELLO WORLD"</code></pre></div></div><hr/>
|
||
<div class="function"><div class="header"> <div class="name"><a name="clink.version_commit">clink.version_commit</a></div> <div class="signature">string variable</div></div><div class="body"><p class="desc">The commit part of the Clink version number. For v1.2.3.<strong>a0f14d</strong> the commit part is a0f14d.</p></div></div><hr/>
|
||
<div class="function"><div class="header"> <div class="name"><a name="clink.version_encoded">clink.version_encoded</a></div> <div class="signature">integer variable</div></div><div class="body"><p class="desc">The Clink version number encoded as a single integer following the format <span class="arg">Mmmmpppp</span> where <span class="arg">M</span> is the major part, <span class="arg">m</span> is the minor part, and <span class="arg">p</span> is the patch part of the version number.</p><p class="desc"> For example, Clink v95.6.723 would be <code>950060723</code>.</p><p class="desc"> This format makes it easy to test for feature availability by encoding version numbers from the release notes.</p></div></div><hr/>
|
||
<div class="function"><div class="header"> <div class="name"><a name="clink.version_major">clink.version_major</a></div> <div class="signature">integer variable</div></div><div class="body"><p class="desc">The major part of the Clink version number. For v<strong>1</strong>.2.3.a0f14d the major version is 1.</p></div></div><hr/>
|
||
<div class="function"><div class="header"> <div class="name"><a name="clink.version_minor">clink.version_minor</a></div> <div class="signature">integer variable</div></div><div class="body"><p class="desc">The minor part of the Clink version number. For v1.<strong>2</strong>.3.a0f14d the minor version is 2.</p></div></div><hr/>
|
||
<div class="function"><div class="header"> <div class="name"><a name="clink.version_patch">clink.version_patch</a></div> <div class="signature">integer variable</div></div><div class="body"><p class="desc">The patch part of the Clink version number. For v1.2.<strong>3</strong>.a0f14d the patch version is 3.</p></div></div><hr/>
|
||
</div><div class="group"><h5 class="group_name"><a name="clink.arg">clink.arg</a></h5><div class="function"><div class="header"> <div class="name"><a name="clink.arg.new_parser">clink.arg.new_parser</a></div> <div class="signature">( ... ) : table</div></div><div class="body deprecated"><p class="desc"><strong>Deprecated; don't use this.</strong> See <a href="#clink.argmatcher">clink.argmatcher</a> for more information.</p><p class="desc">Creates a new parser and adds <span class="arg">...</span> to it.</p><pre class="language-lua"><code>-- Deprecated form:
|
||
local parser = clink.arg.new_parser(
|
||
{ "abc", "def" }, -- arg position 1
|
||
{ "ghi", "jkl" }, -- arg position 2
|
||
"--flag1", "--flag2" -- flags
|
||
)
|
||
|
||
-- Replace with form:
|
||
local parser = clink.argmatcher()
|
||
:addarg("abc", "def") -- arg position 1
|
||
:addarg("ghi", "jkl") -- arg position 2
|
||
:addflags("--flag1", "--flag2") -- flags</code></pre></div></div><hr/>
|
||
<div class="function"><div class="header"> <div class="name"><a name="clink.arg.register_parser">clink.arg.register_parser</a></div> <div class="signature">( <span class="arg_name">cmd</span>:string, <span class="arg_name">parser</span>:table ) : table</div></div><div class="body deprecated"><p class="desc"><strong>Deprecated; don't use this.</strong> See <a href="#clink.argmatcher">clink.argmatcher</a> for more information.</p><p class="desc">Adds <span class="arg">parser</span> to the first argmatcher for <span class="arg">cmd</span>. This behaves similarly to v0.4.8, but not identically. The Clink schema has changed significantly enough that there is no direct 1:1 translation. Calling <code>clink.arg.register_parser</code> repeatedly with the same command to merge parsers is not supported anymore.</p><pre class="language-lua"><code>-- Deprecated form:
|
||
local parser1 = clink.arg.new_parser("abc", "def")
|
||
local parser2 = clink.arg.new_parser("ghi", "jkl")
|
||
clink.arg.register_parser("foo", parser1)
|
||
clink.arg.register_parser("foo", parser2)
|
||
|
||
-- Replace with new form:
|
||
clink.argmatcher("foo"):addarg(parser1, parser2)
|
||
|
||
-- Warning: Note that the following are NOT the same as above!
|
||
-- This replaces parser1 with parser2:
|
||
clink.argmatcher("foo"):addarg(parser1)
|
||
clink.argmatcher("foo"):addarg(parser2)
|
||
-- This uses only parser2 if/when parser1 finishes parsing args:
|
||
clink.argmatcher("foo"):addarg(parser1):addarg(parser2)</code></pre></div></div><hr/>
|
||
</div><div class="group"><h5 class="group_name"><a name="clink.prompt">clink.prompt</a></h5><div class="function"><div class="header"> <div class="name"><a name="clink.prompt.register_filter">clink.prompt.register_filter</a></div> <div class="signature">( <span class="arg_name">filter_func</span>:function, [<span class="arg_name">priority</span>:integer] ) : table</div></div><div class="body deprecated"><p class="desc"><strong>Deprecated; don't use this.</strong> See <a href="#clink.promptfilter">clink.promptfilter</a> for more information.</p><p class="desc">Registers a prompt filter function. The capabilities are the same as before but the syntax is changed.</p><pre class="language-lua"><code>-- Deprecated form:
|
||
function foo_prompt()
|
||
clink.prompt.value = "FOO "..clink.prompt.value.." >>"
|
||
--return true -- Returning true stops further filtering.
|
||
end
|
||
clink.prompt.register_filter(foo_prompt, 10)
|
||
|
||
-- Replace with new form:
|
||
local foo_prompt = clink.promptfilter(10)
|
||
function foo_prompt:filter(prompt)
|
||
return "FOO "..prompt.." >>" --,false -- Adding ,false stops further filtering.
|
||
end</code></pre></div></div><hr/>
|
||
</div><div class="group"><h5 class="group_name"><a name="console">console</a></h5><div class="function"><div class="header"> <div class="name"><a name="console.cellcount">console.cellcount</a></div> <div class="signature">( <span class="arg_name">text</span>:string ) : integer</div></div><div class="body"><p class="desc">Returns the count of visible character cells that would be consumed if the <span class="arg">text</span> string were output to the console, accounting for any ANSI escape codes that may be present in the text.</p><p class="desc"> Note: backspace characters and line endings are counted as visible character cells and will skew the resulting count.</p></div></div><hr/>
|
||
<div class="function"><div class="header"> <div class="name"><a name="console.findnextline">console.findnextline</a></div> <div class="signature">( <span class="arg_name">starting_line</span>:integer, [<span class="arg_name">text</span>:string], [<span class="arg_name">mode</span>:string], [<span class="arg_name">attr</span>:integer], [<span class="arg_name">attrs</span>:table of integers], [<span class="arg_name">mask</span>:string] ) : integer</div></div><div class="body"><p class="desc">Searches downwards (forwards) for a line containing the specified text and/or attributes, starting at line <span class="arg">starting_line</span>. The matching line number is returned, or 0 if no matching line is found.</p><p class="desc"> This behaves the same as <a href="#console.findprevline">console.findprevline()</a> except that it searches in the opposite direction.</p></div></div><hr/>
|
||
<div class="function"><div class="header"> <div class="name"><a name="console.findprevline">console.findprevline</a></div> <div class="signature">( <span class="arg_name">starting_line</span>:integer, [<span class="arg_name">text</span>:string], [<span class="arg_name">mode</span>:string], [<span class="arg_name">attr</span>:integer], [<span class="arg_name">attrs</span>:table of integers], [<span class="arg_name">mask</span>:string] ) : integer</div></div><div class="body"><p class="desc">Searches upwards (backwards) for a line containing the specified text and/or attributes, starting at line <span class="arg">starting_line</span>. The matching line number is returned, or 0 if no matching line is found, or -1 if an invalid regular expression is provided.</p><p class="desc"> You can search for text, attributes, or both. Include the <span class="arg">text</span> argument to search for text, and include either the <span class="arg">attr</span> or <span class="arg">attrs</span> argument to search for attributes. If both text and attribute(s) are passed, then the attribute(s) must be found within the found text. If only attribute(s) are passed, then they must be found anywhere in the line. See <a href="#console.linehascolor">console.linehascolor()</a> for more information about the color codes.</p><p class="desc"> The <span class="arg">mode</span> argument selects how the search behaves. To use a regular expression, pass "regex". To use a case insensitive search, pass "icase". These can be combined by separating them with a comma. The regular expression syntax is the ECMAScript syntax described <a href="https://docs.microsoft.com/en-us/cpp/standard-library/regular-expressions-cpp">here</a>.</p><p class="desc"> Any trailing whitespace is ignored when searching. This especially affects the <code>$</code> (end of line) regex operator.</p><p class="desc"> <span class="arg">mask</span> is optional and can be "fore" or "back" to only match foreground or background colors, respectively.</p><p class="desc"> <strong>Note:</strong> Although most of the arguments are optional, the order of provided arguments is important.</p><p class="desc"> The following example provides a pair of <code>find_prev_colored_line</code> and <code>find_next_colored_line</code> functions. The functions can be bound to keys via the <code>luafunc:</code> macro syntax in a .inputrc file. They scroll the screen buffer to the previous or next line that contains "warn" or "error" colored red or yellow.</p><pre class="language-lua"><code>local was_top
|
||
local found_index
|
||
|
||
local function reset_found()
|
||
was_top = nil
|
||
found_index = nil
|
||
end
|
||
|
||
-- Register for the onbeginedit event, to reset the found
|
||
-- line number each time a new editing prompt begins.
|
||
clink.onbeginedit(reset_found)
|
||
|
||
-- Searches upwards for a line containing "warn" or "error"
|
||
-- colored red or yellow.
|
||
function find_prev_colored_line(rl_buffer)
|
||
local height = console.getheight()
|
||
local cur_top = console.gettop()
|
||
local offset = math.modf((height - 1) / 2) -- For vertically centering the found line.
|
||
|
||
local start
|
||
if found_index == nil or cur_top ~= was_top then
|
||
start = cur_top
|
||
was_top = start
|
||
else
|
||
start = found_index
|
||
end
|
||
|
||
-- Only search if there's still room to scroll up.
|
||
if start - offset > 1 then
|
||
local match = console.findprevline(start - 1, "warn|error", "regex", {4,12,14}, "fore")
|
||
if match ~= nil and match > 0 then
|
||
found_index = match
|
||
end
|
||
end
|
||
|
||
if found_index ~= nil then
|
||
console.scroll("absolute", found_index - offset)
|
||
was_top = console.gettop()
|
||
else
|
||
rl_buffer:ding()
|
||
end
|
||
end
|
||
|
||
-- Searches downwards for a line containing "warn" or "error"
|
||
-- colored red or yellow.
|
||
function find_next_colored_line(rl_buffer)
|
||
if found_index == nil then
|
||
rl_buffer:ding()
|
||
return
|
||
end
|
||
|
||
local height = console.getheight()
|
||
local cur_top = console.gettop()
|
||
local offset = math.modf((height - 1) / 2)
|
||
|
||
local start
|
||
if cur_top ~= was_top then
|
||
start = cur_top + height - 1
|
||
was_top = cur_top
|
||
else
|
||
start = found_index
|
||
end
|
||
|
||
-- Only search if there's still room to scroll down.
|
||
local bottom = console.getnumlines()
|
||
if start - offset + height - 1 < bottom then
|
||
local match = console.findnextline(start + 1, "warn|error", "regex", {4,12,14}, "fore")
|
||
if match ~= nil and match > 0 then
|
||
found_index = match
|
||
end
|
||
end
|
||
|
||
if found_index ~= nil then
|
||
console.scroll("absolute", found_index - offset)
|
||
was_top = console.gettop()
|
||
else
|
||
rl_buffer:ding()
|
||
end
|
||
end</code></pre></div></div><hr/>
|
||
<div class="function"><div class="header"> <div class="name"><a name="console.getheight">console.getheight</a></div> <div class="signature">() : integer</div></div><div class="body"><p class="desc">Returns the number of visible lines of the console screen buffer.</p></div></div><hr/>
|
||
<div class="function"><div class="header"> <div class="name"><a name="console.getlinetext">console.getlinetext</a></div> <div class="signature">( <span class="arg_name">line</span>:integer ) : string</div></div><div class="body"><p class="desc">Returns the text from line number <span class="arg">line</span>, from 1 to <a href="#console.getnumlines">console.getnumlines()</a>.</p><p class="desc"> Any trailing whitespace is stripped before returning the text.</p></div></div><hr/>
|
||
<div class="function"><div class="header"> <div class="name"><a name="console.getnumlines">console.getnumlines</a></div> <div class="signature">() : integer</div></div><div class="body"><p class="desc">Returns the total number of lines in the console screen buffer.</p></div></div><hr/>
|
||
<div class="function"><div class="header"> <div class="name"><a name="console.gettitle">console.gettitle</a></div> <div class="signature">() : string</div></div><div class="body"><p class="desc">Returns the console title text.</p></div></div><hr/>
|
||
<div class="function"><div class="header"> <div class="name"><a name="console.gettop">console.gettop</a></div> <div class="signature">() : integer</div></div><div class="body"><p class="desc">Returns the current top line (scroll position) in the console screen buffer.</p></div></div><hr/>
|
||
<div class="function"><div class="header"> <div class="name"><a name="console.getwidth">console.getwidth</a></div> <div class="signature">() : integer</div></div><div class="body"><p class="desc">Returns the width of the console screen buffer in characters.</p></div></div><hr/>
|
||
<div class="function"><div class="header"> <div class="name"><a name="console.islinedefaultcolor">console.islinedefaultcolor</a></div> <div class="signature">( <span class="arg_name">line</span>:integer ) : boolean</div></div><div class="body"><p class="desc">Returns whether line number <span class="arg">line</span> uses only the default text color.</p></div></div><hr/>
|
||
<div class="function"><div class="header"> <div class="name"><a name="console.linehascolor">console.linehascolor</a></div> <div class="signature">( <span class="arg_name">line</span>:integer, [<span class="arg_name">attr</span>:integer], [<span class="arg_name">attrs</span>:table of integers], [<span class="arg_name">mask</span>:string] ) : boolean</div></div><div class="body"><p class="desc">Returns whether line number <span class="arg">line</span> contains the DOS color code <span class="arg">attr</span>, or any of the DOS color codes in <span class="arg">attrs</span> (either an integer or a table of integers must be provided, but not both). <span class="arg">mask</span> is optional and can be "fore" or "back" to only match foreground or background colors, respectively.</p><p class="desc"> The low 4 bits of the color code are the foreground color, and the high 4 bits of the color code are the background color. This refers to the default 16 color palette used by console windows. When 256 color or 24-bit color ANSI escape codes have been used, the closest of the 16 colors is used.</p><p class="desc"> To build a color code, add the corresponding Foreground color and the Background color values from this table:</p><p class="desc"> <table><tr><th align="center">Foreground</th><th align="center">Background</th><th>Color</th></tr> <tr><td align="center">0</td><td align="center">0</td><td><div class="colorsample" style="background-color:#000000"> </div> Black</td></tr> <tr><td align="center">1</td><td align="center">16</td><td><div class="colorsample" style="background-color:#000080"> </div> Dark Blue</td></tr> <tr><td align="center">2</td><td align="center">32</td><td><div class="colorsample" style="background-color:#008000"> </div> Dark Green</td></tr> <tr><td align="center">3</td><td align="center">48</td><td><div class="colorsample" style="background-color:#008080"> </div> Dark Cyan</td></tr> <tr><td align="center">4</td><td align="center">64</td><td><div class="colorsample" style="background-color:#800000"> </div> Dark Red</td></tr> <tr><td align="center">5</td><td align="center">80</td><td><div class="colorsample" style="background-color:#800080"> </div> Dark Magenta</td></tr> <tr><td align="center">6</td><td align="center">96</td><td><div class="colorsample" style="background-color:#808000"> </div> Dark Yellow</td></tr> <tr><td align="center">7</td><td align="center">112</td><td><div class="colorsample" style="background-color:#c0c0c0"> </div> Gray</td></tr> <tr><td align="center">8</td><td align="center">128</td><td><div class="colorsample" style="background-color:#808080"> </div> Dark Gray</td></tr> <tr><td align="center">9</td><td align="center">144</td><td><div class="colorsample" style="background-color:#0000ff"> </div> Bright Blue</td></tr> <tr><td align="center">10</td><td align="center">160</td><td><div class="colorsample" style="background-color:#00ff00"> </div> Bright Green</td></tr> <tr><td align="center">11</td><td align="center">176</td><td><div class="colorsample" style="background-color:#00ffff"> </div> Bright Cyan</td></tr> <tr><td align="center">12</td><td align="center">192</td><td><div class="colorsample" style="background-color:#ff0000"> </div> Bright Red</td></tr> <tr><td align="center">13</td><td align="center">208</td><td><div class="colorsample" style="background-color:#ff00ff"> </div> Bright Magenta</td></tr> <tr><td align="center">14</td><td align="center">224</td><td><div class="colorsample" style="background-color:#ffff00"> </div> Bright Yellow</td></tr> <tr><td align="center">15</td><td align="center">240</td><td><div class="colorsample" style="background-color:#ffffff"> </div> White</td></tr> </table></p></div></div><hr/>
|
||
<div class="function"><div class="header"> <div class="name"><a name="console.plaintext">console.plaintext</a></div> <div class="signature">( <span class="arg_name">text</span>:string ) : string, integer</div></div><div class="body"><p class="desc">Returns the input <span class="arg">text</span> with ANSI escape codes removed, and the count of visible character cells that would be consumed if the text were output to the console.</p><p class="desc"> Note: backspace characters and line endings are counted as visible character cells and will skew the resulting count.</p></div></div><hr/>
|
||
<div class="function"><div class="header"> <div class="name"><a name="console.screengrab">console.screengrab</a></div> <div class="signature">( <span class="arg_name">candidate_pattern</span>:string, <span class="arg_name">accept_pattern</span>:string ) : table</div></div><div class="body"><p class="desc">Uses the provided Lua string patterns to collect text from the current console screen and returns a table of matching text snippets. The snippets are ordered by distance from the input line.</p><p class="desc"> For example <span class="arg">candidate_pattern</span> could specify a pattern that identifies words, and <span class="arg">accept_pattern</span> could specify a pattern that matches words composed of hexadecimal digits.</p><pre class="language-lua"><code>local matches = console.screengrab(
|
||
"[^%w]*(%w%w[%w]+)", -- Words with 3 or more letters are candidates.
|
||
"^%x+$") -- A candidate containing only hexadecimal digits is a match.</code></pre></div></div><hr/>
|
||
<div class="function"><div class="header"> <div class="name"><a name="console.scroll">console.scroll</a></div> <div class="signature">( <span class="arg_name">mode</span>:string, <span class="arg_name">amount</span>:integer ) : integer</div></div><div class="body"><p class="desc">Scrolls the console screen buffer and returns the number of lines scrolled up (negative) or down (positive).</p><p class="desc"> The <span class="arg">mode</span> specifies how to scroll: <table> <tr><th>Mode</th><th>Description</th></tr> <tr><td>"line"</td><td>Scrolls by <span class="arg">amount</span> lines; negative is up and positive is down.</td></tr> <tr><td>"page"</td><td>Scrolls by <span class="arg">amount</span> pages; negative is up and positive is down.</td></tr> <tr><td>"end"</td><td>Scrolls to the top if <span class="arg">amount</span> is negative, or to the bottom if positive.</td></tr> <tr><td>"absolute"</td><td>Scrolls to line <span class="arg">amount</span>, from 1 to <a href="#console.getnumlines">console.getnumlines()</a>.</td></tr> </table></p></div></div><hr/>
|
||
<div class="function"><div class="header"> <div class="name"><a name="console.settitle">console.settitle</a></div> <div class="signature">( <span class="arg_name">title</span>:string ) : nil</div></div><div class="body"><p class="desc">Sets the console title text.</p></div></div><hr/>
|
||
</div><div class="group"><h5 class="group_name"><a name="io">io</a></h5><div class="function"><div class="header"> <div class="name"><a name="io.popenrw">io.popenrw</a></div> <div class="signature">( <span class="arg_name">command</span>:string, [<span class="arg_name">mode</span>:string] ) : file, file</div></div><div class="body"><p class="desc">Runs <code>command</code> and returns two file handles: a file handle for reading output from the command, and a file handle for writing input to the command.</p><p class="desc"> <span class="arg">mode</span> can be <code>"t"</code> for text mode (the default if omitted) or <code>"b"</code> for binary mode.</p><p class="desc"> If the function fails it returns nil, an error message, and an error number.</p><p class="desc"> <fieldset><legend>Warning</legend> This can result in deadlocks unless the command fully reads all of its input before writing any output. This is because Lua uses blocking IO to read and write file handles. If the write buffer fills (or the read buffer is empty) then the write (or read) will block and can only become unblocked if the command correspondingly reads (or writes). But the other command can easily experience the same blocking IO problem on its end, resulting in a deadlock: process 1 is blocked from writing more until process 2 reads, but process 2 can't read because it is blocked from writing until process 1 reads. </fieldset></p><pre class="language-lua"><code>local r,w = io.popenrw("fzf.exe --height 40%")
|
||
|
||
w:write("hello\n")
|
||
w:write("world\n")
|
||
w:close()
|
||
|
||
while (true) do
|
||
local line = r:read("*line")
|
||
if not line then
|
||
break
|
||
end
|
||
print(line)
|
||
end
|
||
r:close()</code></pre></div></div><hr/>
|
||
</div><div class="group"><h5 class="group_name"><a name="line">line</a></h5><div class="function"><div class="header"> <div class="name"><a name="line:getcommandoffset">line:getcommandoffset</a></div> <div class="signature">() : integer</div></div><div class="body"><p class="desc">Returns the offset to the start of the delimited command in the line that's being effectively edited. Note that this may not be the offset of the first command of the line unquoted as whitespace isn't considered for words.</p><pre class="language-lua"><code>-- Given the following line; abc& 123
|
||
-- where commands are separated by & symbols.
|
||
line:getcommandoffset() == 4</code></pre></div></div><hr/>
|
||
<div class="function"><div class="header"> <div class="name"><a name="line:getcursor">line:getcursor</a></div> <div class="signature">() : integer</div></div><div class="body"><p class="desc">Returns the position of the cursor.</p></div></div><hr/>
|
||
<div class="function"><div class="header"> <div class="name"><a name="line:getendword">line:getendword</a></div> <div class="signature">() : string</div></div><div class="body"><p class="desc">Returns the last word of the line. This is the word that matches are being generated for.</p><p class="desc"> Note: The returned word omits any quotes. This helps generators naturally complete <code>"foo\"ba</code> to <code>"foo\bar"</code>. The raw word including quotes can be obtained using the <code>offset</code> and <code>length</code> fields from <a href="#line:getwordinfo">line:getwordinfo()</a> to extract a substring from the line returned by <a href="#line:getline">line:getline()</a>.</p><pre class="language-lua"><code>line:getword(line:getwordcount()) == line:getendword()</code></pre></div></div><hr/>
|
||
<div class="function"><div class="header"> <div class="name"><a name="line:getline">line:getline</a></div> <div class="signature">() : string</div></div><div class="body"><p class="desc">Returns the current line in its entirety.</p></div></div><hr/>
|
||
<div class="function"><div class="header"> <div class="name"><a name="line:getword">line:getword</a></div> <div class="signature">( <span class="arg_name">index</span>:integer ) : string</div></div><div class="body"><p class="desc">Returns the word of the line at <span class="arg">index</span>.</p><p class="desc"> Note: The returned word omits any quotes. This helps generators naturally complete <code>"foo\"ba</code> to <code>"foo\bar"</code>. The raw word including quotes can be obtained using the <code>offset</code> and <code>length</code> fields from <a href="#line:getwordinfo">line:getwordinfo()</a> to extract a substring from the line returned by <a href="#line:getline">line:getline()</a>.</p></div></div><hr/>
|
||
<div class="function"><div class="header"> <div class="name"><a name="line:getwordcount">line:getwordcount</a></div> <div class="signature">() : integer</div></div><div class="body"><p class="desc">Returns the number of words in the current line.</p></div></div><hr/>
|
||
<div class="function"><div class="header"> <div class="name"><a name="line:getwordinfo">line:getwordinfo</a></div> <div class="signature">( <span class="arg_name">index</span>:integer ) : table</div></div><div class="body"><p class="desc">Returns a table of information about the Nth word in the line.</p><p class="desc"> Note: The length refers to the substring in the line; it omits leading and trailing quotes, but <em><strong>includes</strong></em> embedded quotes. <a href="#line:getword">line:getword()</a> conveniently strips embedded quotes to help generators naturally complete <code>"foo\"ba</code> to <code>"foo\bar"</code>.</p><p class="desc"> The table returned has the following scheme:</p><pre class="language-lua"><code>{
|
||
offset, -- [integer] offset where the word starts in the line:getline() string.
|
||
length, -- [integer] length of the word (includes embedded quotes).
|
||
quoted, -- [boolean] indicates whether the word is quoted.
|
||
delim, -- [string] the delimiter character, or an empty string.
|
||
alias, -- [boolean | nil] true if the word is a doskey alias, otherwise nil.
|
||
}</code></pre></div></div><hr/>
|
||
</div><div class="group"><h5 class="group_name"><a name="log">log</a></h5><div class="function"><div class="header"> <div class="name"><a name="log.info">log.info</a></div> <div class="signature">( <span class="arg_name">message</span>:string ) : nil</div></div><div class="body"><p class="desc">Writes info <span class="arg">message</span> to the Clink log file. Use this sparingly, or it could cause performance problems or disk space problems.</p></div></div><hr/>
|
||
</div><div class="group"><h5 class="group_name"><a name="os">os</a></h5><div class="function"><div class="header"> <div class="name"><a name="os.chdir">os.chdir</a></div> <div class="signature">( <span class="arg_name">path</span>:string ) : boolean</div></div><div class="body"><p class="desc">Changes the current directory to <span class="arg">path</span> and returns whether it was successful.</p></div></div><hr/>
|
||
<div class="function"><div class="header"> <div class="name"><a name="os.copy">os.copy</a></div> <div class="signature">( <span class="arg_name">src</span>:string, <span class="arg_name">dest</span>:string ) : boolean</div></div><div class="body"><p class="desc">Copies the <span class="arg">src</span> file to the <span class="arg">dest</span> file.</p></div></div><hr/>
|
||
<div class="function"><div class="header"> <div class="name"><a name="os.createtmpfile">os.createtmpfile</a></div> <div class="signature">( [<span class="arg_name">prefix</span>:string], [<span class="arg_name">ext</span>:string], [<span class="arg_name">path</span>:string], [<span class="arg_name">mode</span>:string] ) : file, string</div></div><div class="body"><p class="desc">Creates a uniquely named file, intended for use as a temporary file. The name pattern is "<em>location</em> <code>\</code> <em>prefix</em> <code>_</code> <em>processId</em> <code>_</code> <em>uniqueNum</em> <em>extension</em>".</p><p class="desc"> <span class="arg">prefix</span> optionally specifies a prefix for the file name and defaults to "tmp".</p><p class="desc"> <span class="arg">ext</span> optionally specifies a suffix for the file name and defaults to "" (if <span class="arg">ext</span> starts with a period "." then it is a filename extension).</p><p class="desc"> <span class="arg">path</span> optionally specifies a path location in which to create the file. The default is the system TEMP directory.</p><p class="desc"> <span class="arg">mode</span> optionally specifies "t" for text mode (line endings are translated) or "b" for binary mode (untranslated IO). The default is "t".</p><p class="desc"> When successful, the function returns a file handle and the file name.</p><p class="desc"> <strong>Note:</strong> Be sure to delete the file when finished, or it will be leaked.</p><p class="desc"> If the function is unable to create a file it returns nil, an error message, and an error number. For example if the directory is inaccessible, or if there are already too many files, or invalid file name characters are used, or etc.</p></div></div><hr/>
|
||
<div class="function"><div class="header"> <div class="name"><a name="os.expandenv">os.expandenv</a></div> <div class="signature">( <span class="arg_name">value</span>:string ) : string</div></div><div class="body"><p class="desc">Returns <span class="arg">value</span> with any <code>%name%</code> environment variables expanded. Names are case insensitive. Special CMD syntax is not supported (e.g. <code>%name:str1=str2%</code> or <code>%name:~offset,length%</code>).</p><p class="desc"> Note: <code>os.getenv("HOME")</code> receives special treatment: if %HOME% is not set then it is synthesized from %HOMEDRIVE% and %HOMEPATH%, or from %USERPROFILE%.</p></div></div><hr/>
|
||
<div class="function"><div class="header"> <div class="name"><a name="os.getalias">os.getalias</a></div> <div class="signature">( <span class="arg_name">name</span>:string ) : string | nil</div></div><div class="body"><p class="desc">Returns command string for doskey alias <span class="arg">name</span>, or nil if the named alias does not exist.</p></div></div><hr/>
|
||
<div class="function"><div class="header"> <div class="name"><a name="os.getaliases">os.getaliases</a></div> <div class="signature">() : table</div></div><div class="body"><p class="desc">Returns doskey aliases in a table with the following scheme: <span class="tablescheme">{ {name:string, command:string}, ... }</span>.</p></div></div><hr/>
|
||
<div class="function"><div class="header"> <div class="name"><a name="os.getbatterystatus">os.getbatterystatus</a></div> <div class="signature">() : table</div></div><div class="body"><p class="desc">Returns a table containing the battery status for the device, or nil if an error occurs. The returned table has the following scheme:</p><pre class="language-lua"><code>{
|
||
level, -- [integer] the battery life from 0 to 100, or -1 if an
|
||
-- error occurred or there is no battery.
|
||
acpower, -- [boolean] whether the device is connected to AC power.
|
||
charging, -- [boolean] whether the battery is charging.
|
||
batterysaver, -- [boolean] whether Battery Saver mode is active.
|
||
}</code></pre></div></div><hr/>
|
||
<div class="function"><div class="header"> <div class="name"><a name="os.getcwd">os.getcwd</a></div> <div class="signature">() : string</div></div><div class="body"><p class="desc">Returns the current directory.</p></div></div><hr/>
|
||
<div class="function"><div class="header"> <div class="name"><a name="os.getenv">os.getenv</a></div> <div class="signature">( <span class="arg_name">name</span>:string ) : string | nil</div></div><div class="body"><p class="desc">Returns the value of the named environment variable, or nil if it doesn't exist.</p><p class="desc"> Note: <code>os.getenv("HOME")</code> receives special treatment: if %HOME% is not set then it is synthesized from %HOMEDRIVE% and %HOMEPATH%, or from %USERPROFILE%.</p></div></div><hr/>
|
||
<div class="function"><div class="header"> <div class="name"><a name="os.getenvnames">os.getenvnames</a></div> <div class="signature">() : table</div></div><div class="body"><p class="desc">Returns all environment variables in a table with the following scheme: <span class="tablescheme">{ {name:string, value:string}, ... }</span>.</p></div></div><hr/>
|
||
<div class="function"><div class="header"> <div class="name"><a name="os.getfullpathname">os.getfullpathname</a></div> <div class="signature">( <span class="arg_name">path</span>:string ) : string</div></div><div class="body"><p class="desc">Returns the full path name for <span class="arg">path</span>.</p></div></div><hr/>
|
||
<div class="function"><div class="header"> <div class="name"><a name="os.gethost">os.gethost</a></div> <div class="signature">() : string</div></div><div class="body"><p class="desc">Returns the fully qualified file name of the host process. Currently only CMD.EXE can host Clink.</p></div></div><hr/>
|
||
<div class="function"><div class="header"> <div class="name"><a name="os.getlongpathname">os.getlongpathname</a></div> <div class="signature">( <span class="arg_name">path</span>:string ) : string</div></div><div class="body"><p class="desc">Returns the long path name for <span class="arg">path</span>.</p></div></div><hr/>
|
||
<div class="function"><div class="header"> <div class="name"><a name="os.getpid">os.getpid</a></div> <div class="signature">() : integer</div></div><div class="body"><p class="desc">Returns the CMD.EXE process ID. This is mainly intended to help with salting unique resource names (for example named pipes).</p></div></div><hr/>
|
||
<div class="function"><div class="header"> <div class="name"><a name="os.getscreeninfo">os.getscreeninfo</a></div> <div class="signature">() : table</div></div><div class="body"><p class="desc">Returns dimensions of the terminal's buffer and visible window. The returned table has the following scheme:</p><pre class="language-lua"><code>{
|
||
bufwidth, -- [integer] width of the screen buffer
|
||
bufheight, -- [integer] height of the screen buffer
|
||
winwidth, -- [integer] width of the visible window
|
||
winheight, -- [integer] height of the visible window
|
||
}</code></pre></div></div><hr/>
|
||
<div class="function"><div class="header"> <div class="name"><a name="os.getshortpathname">os.getshortpathname</a></div> <div class="signature">( <span class="arg_name">path</span>:string ) : string</div></div><div class="body"><p class="desc">Returns the 8.3 short path name for <span class="arg">path</span>. This may return the input path if an 8.3 short path name is not available.</p></div></div><hr/>
|
||
<div class="function"><div class="header"> <div class="name"><a name="os.globdirs">os.globdirs</a></div> <div class="signature">( <span class="arg_name">globpattern</span>:string, [<span class="arg_name">extrainfo</span>:boolean] ) : table</div></div><div class="body"><p class="desc">Collects directories matching <span class="arg">globpattern</span> and returns them in a table of strings.</p><p class="desc"> When <span class="arg">extrainfo</span> is true, then the returned table has the following scheme: <span class="tablescheme">{ {name:string, type:string}, ... }</span>.</p><p class="desc"> The <span class="tablescheme">type</span> string can be "file" or "dir", and may also contain ",hidden" and ",readonly" depending on the attributes (making it usable as a match type for <a href="#builder:addmatch">builder:addmatch()</a>).</p><p class="desc"> Note: any quotation marks (<code>"</code>) in <span class="arg">globpattern</span> are stripped.</p></div></div><hr/>
|
||
<div class="function"><div class="header"> <div class="name"><a name="os.globfiles">os.globfiles</a></div> <div class="signature">( <span class="arg_name">globpattern</span>:string, [<span class="arg_name">extrainfo</span>:boolean] ) : table</div></div><div class="body"><p class="desc">Collects files and/or directories matching <span class="arg">globpattern</span> and returns them in a table of strings.</p><p class="desc"> When <span class="arg">extrainfo</span> is true, then the returned table has the following scheme: <span class="tablescheme">{ {name:string, type:string}, ... }</span>.</p><p class="desc"> The <span class="tablescheme">type</span> string can be "file" or "dir", and may also contain ",hidden" and ",readonly" depending on the attributes (making it usable as a match type for <a href="#builder:addmatch">builder:addmatch()</a>).</p><p class="desc"> Note: any quotation marks (<code>"</code>) in <span class="arg">globpattern</span> are stripped.</p></div></div><hr/>
|
||
<div class="function"><div class="header"> <div class="name"><a name="os.isdir">os.isdir</a></div> <div class="signature">( <span class="arg_name">path</span>:string ) : boolean</div></div><div class="body"><p class="desc">Returns whether <span class="arg">path</span> is a directory.</p></div></div><hr/>
|
||
<div class="function"><div class="header"> <div class="name"><a name="os.isfile">os.isfile</a></div> <div class="signature">( <span class="arg_name">path</span>:string ) : boolean</div></div><div class="body"><p class="desc">Returns whether <span class="arg">path</span> is a file.</p></div></div><hr/>
|
||
<div class="function"><div class="header"> <div class="name"><a name="os.ishidden">os.ishidden</a></div> <div class="signature">( <span class="arg_name">path</span>:string ) : boolean</div></div><div class="body"><p class="desc">Returns whether <span class="arg">path</span> has the hidden attribute set.</p></div></div><hr/>
|
||
<div class="function"><div class="header"> <div class="name"><a name="os.mkdir">os.mkdir</a></div> <div class="signature">( <span class="arg_name">path</span>:string ) : boolean</div></div><div class="body"><p class="desc">Creates the directory <span class="arg">path</span> and returns whether it was successful.</p></div></div><hr/>
|
||
<div class="function"><div class="header"> <div class="name"><a name="os.move">os.move</a></div> <div class="signature">( <span class="arg_name">src</span>:string, <span class="arg_name">dest</span>:string ) : boolean</div></div><div class="body"><p class="desc">Moves the <span class="arg">src</span> file to the <span class="arg">dest</span> file.</p></div></div><hr/>
|
||
<div class="function"><div class="header"> <div class="name"><a name="os.rmdir">os.rmdir</a></div> <div class="signature">( <span class="arg_name">path</span>:string ) : boolean</div></div><div class="body"><p class="desc">Removes the directory <span class="arg">path</span> and returns whether it was successful.</p></div></div><hr/>
|
||
<div class="function"><div class="header"> <div class="name"><a name="os.setenv">os.setenv</a></div> <div class="signature">( <span class="arg_name">name</span>:string, <span class="arg_name">value</span>:string ) : boolean</div></div><div class="body"><p class="desc">Sets the <span class="arg">name</span> environment variable to <span class="arg">value</span> and returns whether it was successful.</p></div></div><hr/>
|
||
<div class="function"><div class="header"> <div class="name"><a name="os.unlink">os.unlink</a></div> <div class="signature">( <span class="arg_name">path</span>:string ) : boolean</div></div><div class="body"><p class="desc">Deletes the file <span class="arg">path</span> and returns whether it was successful.</p></div></div><hr/>
|
||
</div><div class="group"><h5 class="group_name"><a name="path">path</a></h5><div class="function"><div class="header"> <div class="name"><a name="path.getbasename">path.getbasename</a></div> <div class="signature">( <span class="arg_name">path</span>:string ) : string</div></div><div class="body"><p class="desc"></p><pre class="language-lua"><code>path.getbasename("/foo/bar.ext") -- returns "bar"
|
||
path.getbasename("") -- returns ""
|
||
path.getbasename(nil) -- returns nil</code></pre></div></div><hr/>
|
||
<div class="function"><div class="header"> <div class="name"><a name="path.getdirectory">path.getdirectory</a></div> <div class="signature">( <span class="arg_name">path</span>:string ) : nil or string</div></div><div class="body"><p class="desc">This is similar to <a href="#path.toparent">path.toparent()</a> but can behave differently when the input path ends with a path separator. This is the recommended API for parsing a path into its component pieces, but is not recommended for walking up through parent directories.</p><pre class="language-lua"><code>path.getdirectory("foo") -- returns nil
|
||
path.getdirectory("\foo") -- returns "\"
|
||
path.getdirectory("c:foo") -- returns "c:"
|
||
path.getdirectory([[c:\]]) -- returns "c:\"
|
||
path.getdirectory("c:\foo") -- returns "c:\"
|
||
path.getdirectory("c:\foo\bar") -- returns "c:\foo"
|
||
path.getdirectory("\\foo\bar") -- returns "\\foo\bar"
|
||
path.getdirectory("\\foo\bar\dir") -- returns "\\foo\bar"
|
||
path.getdirectory("") -- returns nil
|
||
path.getdirectory(nil) -- returns nil
|
||
|
||
-- These split the path components differently than path.toparent().
|
||
path.getdirectory([[c:\foo\bar\]]) -- returns "c:\foo\bar"
|
||
path.getdirectory([[\\foo\bar\dir\]]) -- returns "\\foo\bar\dir"</code></pre></div></div><hr/>
|
||
<div class="function"><div class="header"> <div class="name"><a name="path.getdrive">path.getdrive</a></div> <div class="signature">( <span class="arg_name">path</span>:string ) : nil or string</div></div><div class="body"><p class="desc"></p><pre class="language-lua"><code>path.getdrive("e:/foo/bar") -- returns "e:"
|
||
path.getdrive("foo/bar") -- returns nil
|
||
path.getdrive("") -- returns nil
|
||
path.getdrive(nil) -- returns nil</code></pre></div></div><hr/>
|
||
<div class="function"><div class="header"> <div class="name"><a name="path.getextension">path.getextension</a></div> <div class="signature">( <span class="arg_name">path</span>:string ) : string</div></div><div class="body"><p class="desc"></p><pre class="language-lua"><code>path.getextension("bar.ext") -- returns ".ext"
|
||
path.getextension("bar") -- returns ""
|
||
path.getextension("") -- returns ""
|
||
path.getextension(nil) -- returns nil</code></pre></div></div><hr/>
|
||
<div class="function"><div class="header"> <div class="name"><a name="path.getname">path.getname</a></div> <div class="signature">( <span class="arg_name">path</span>:string ) : string</div></div><div class="body"><p class="desc"></p><pre class="language-lua"><code>path.getname("/foo/bar.ext") -- returns "bar.ext"
|
||
path.getname("") -- returns ""
|
||
path.getname(nil) -- returns nil</code></pre></div></div><hr/>
|
||
<div class="function"><div class="header"> <div class="name"><a name="path.isexecext">path.isexecext</a></div> <div class="signature">( <span class="arg_name">path</span>:string ) : boolean</div></div><div class="body"><p class="desc">Examines the extension of the path name. Returns true if the extension is listed in %PATHEXT%. This caches the extensions in a map so that it's more efficient than getting and parsing %PATHEXT% each time.</p><pre class="language-lua"><code>path.isexecext("program.exe") -- returns true
|
||
path.isexecext("file.doc") -- returns false
|
||
path.isexecext("") -- returns false
|
||
path.isexecext(nil) -- returns nil</code></pre></div></div><hr/>
|
||
<div class="function"><div class="header"> <div class="name"><a name="path.join">path.join</a></div> <div class="signature">( <span class="arg_name">left</span>:string, <span class="arg_name">right</span>:string ) : string</div></div><div class="body"><p class="desc"></p><pre class="language-lua"><code>path.join("/foo", "bar") -- returns "/foo\bar"
|
||
path.join("", "bar") -- returns "bar"
|
||
path.join("/foo", "") -- returns "/foo"
|
||
path.join(nil, "bar") -- returns nil
|
||
path.join("/foo", nil) -- returns nil</code></pre></div></div><hr/>
|
||
<div class="function"><div class="header"> <div class="name"><a name="path.normalise">path.normalise</a></div> <div class="signature">( <span class="arg_name">path</span>:string, [<span class="arg_name">separator</span>:string] ) : string</div></div><div class="body"><p class="desc">Cleans <span class="arg">path</span> by normalising separators and removing "." and ".." elements. If <span class="arg">separator</span> is provided it is used to delimit path elements, otherwise a system-specific delimiter is used.</p><pre class="language-lua"><code>path.normalise("a////b/\\/c/") -- returns "a\b\c\"
|
||
path.normalise("") -- returns ""
|
||
path.normalise(nil) -- returns nil</code></pre></div></div><hr/>
|
||
<div class="function"><div class="header"> <div class="name"><a name="path.toparent">path.toparent</a></div> <div class="signature">( <span class="arg_name">path</span>:string ) : parent:string, child:string</div></div><div class="body"><p class="desc">Splits the last path component from <span class="arg">path</span>, if possible. Returns the result and the component that was split, if any.</p><p class="desc"> This is similar to <a href="#path.getdirectory">path.getdirectory()</a> but can behave differently when the input path ends with a path separator. This is the recommended API for walking up through parent directories.</p><pre class="language-lua"><code>local parent,child
|
||
parent,child = path.toparent("foo") -- returns "", "foo"
|
||
parent,child = path.toparent("\foo") -- returns "\", "foo"
|
||
parent,child = path.toparent("c:foo") -- returns "c:", "foo"
|
||
parent,child = path.toparent([[c:\]]) -- returns "c:\", ""
|
||
parent,child = path.toparent("c:\foo") -- returns "c:\", "foo"
|
||
parent,child = path.toparent("c:\foo\bar") -- returns "c:\foo", "bar"
|
||
parent,child = path.toparent("\\foo\bar") -- returns "\\foo\bar", ""
|
||
parent,child = path.toparent("\\foo\bar\dir") -- returns "\\foo\bar", "dir"
|
||
parent,child = path.toparent("") -- returns "", ""
|
||
parent,child = path.toparent(nil) -- returns nil
|
||
|
||
-- These split the path components differently than path.getdirectory().
|
||
parent,child = path.toparent([[c:\foo\bar\]]) -- returns "c:\foo", "bar"
|
||
parent,child = path.toparent([[\\foo\bar\dir\]])-- returns "\\foo\bar", "dir"</code></pre></div></div><hr/>
|
||
</div><div class="group"><h5 class="group_name"><a name="rl">rl</a></h5><div class="function"><div class="header"> <div class="name"><a name="rl.collapsetilde">rl.collapsetilde</a></div> <div class="signature">( <span class="arg_name">path</span>:string, [<span class="arg_name">force</span>:boolean] ) : string</div></div><div class="body"><p class="desc">Undoes Readline tilde expansion. See <a href="#rl.expandtilde">rl.expandtilde</a> for more information.</p><pre class="language-lua"><code>rl.collapsetilde("C:\Users\yourusername\Documents")
|
||
|
||
-- The return value depends on the expand-tilde configuration variable:
|
||
-- When "on", the function returns "C:\Users\yourusername\Documents".
|
||
-- When "off", the function returns "~\Documents".
|
||
|
||
-- Or when <span class="arg">force</span> is true, the function returns "~\Documents".</code></pre></div></div><hr/>
|
||
<div class="function"><div class="header"> <div class="name"><a name="rl.expandtilde">rl.expandtilde</a></div> <div class="signature">( <span class="arg_name">path</span>:string ) : string, boolean</div></div><div class="body"><p class="desc">Performs Readline tilde expansion.</p><p class="desc"> When generating filename matches for a word, use the <a href="#rl.expandtilde">rl.expandtilde</a> and <a href="#rl.collapsetilde">rl.collapsetilde</a> helper functions to perform tilde completion expansion according to Readline's configuration.</p><p class="desc"> Use <a href="#rl.expandtilde">rl.expandtilde</a> to do tilde expansion before collecting file matches (e.g. via <a href="#os.globfiles">os.globfiles</a>). If it indicates that it expanded the string, then use <a href="#rl.collapsetilde">rl.collapsetilde</a> to put back the tilde before returning a match.</p><pre class="language-lua"><code>local result, expanded = rl.expandtilde("~\Documents")
|
||
-- result is "C:\Users\yourusername\Documents"
|
||
-- expanded is true
|
||
|
||
-- This dir_matches function demonstrates efficient use of rl.expandtilde()
|
||
-- and rl.collapsetilde() to generate directory matches from the file system.
|
||
function dir_matches(match_word, word_index, line_state)
|
||
-- Expand tilde before scanning file system.
|
||
local word = line_state:getword(word_index)
|
||
local expanded
|
||
word, expanded = rl.expandtilde(word)
|
||
|
||
-- Get the directory from 'word', and collapse tilde before generating
|
||
-- matches. Notice that collapsetilde() only needs to be called once!
|
||
local root = path.getdirectory(word) or ""
|
||
if expanded then
|
||
root = rl.collapsetilde(root)
|
||
end
|
||
|
||
local matches = {}
|
||
for _, d in ipairs(os.globdirs(word.."*", true)) do
|
||
-- Join the filename with the input directory (might have a tilde).
|
||
local dir = path.join(root, d.name)
|
||
table.insert(matches, { match = dir, type = d.type })
|
||
end
|
||
return matches
|
||
end</code></pre></div></div><hr/>
|
||
<div class="function"><div class="header"> <div class="name"><a name="rl.getlastcommand">rl.getlastcommand</a></div> <div class="signature">() : string, function</div></div><div class="body"><p class="desc">Returns two values: <ul> <li>The name of the last Readline command invoked by a key binding. <li>The name of the last Lua function invoked by a key binding. </ul></p><p class="desc"> If the last key binding invoked a Lua function, then the first return value is an empty string unless the Lua function used <a href="#rl.invokecommand">rl.invokecommand()</a> to also internally invoke a Readline command. If the last key binding did not invoke a Lua function, then the second return value is an empty string.</p><pre class="language-lua"><code>local last_rl_func, last_lua_func = rl.getlastcommand()</code></pre></div></div><hr/>
|
||
<div class="function"><div class="header"> <div class="name"><a name="rl.getvariable">rl.getvariable</a></div> <div class="signature">( <span class="arg_name">name</span>:string ) : string | nil</div></div><div class="body"><p class="desc">Returns the value of the named Readline configuration variable as a string, or nil if the variable name is not recognized.</p></div></div><hr/>
|
||
<div class="function"><div class="header"> <div class="name"><a name="rl.invokecommand">rl.invokecommand</a></div> <div class="signature">( <span class="arg_name">command</span>:string, [<span class="arg_name">count</span>:integer] ) : boolean | nil</div></div><div class="body"><p class="desc">Invokes a Readline command named <span class="arg">command</span>. May only be used within a <code>luafunc:</code> key binding.</p><p class="desc"> <span class="arg">count</span> is optional and defaults to 1 if omitted.</p><p class="desc"> Returns true if the named command succeeds, false if the named command fails, or nil if the named command doesn't exist.</p><p class="desc"> Warning: Invoking more than one Readline command in a <code>luafunc:</code> key binding could have unexpected results, depending on which commands are invoked.</p></div></div><hr/>
|
||
<div class="function"><div class="header"> <div class="name"><a name="rl.isvariabletrue">rl.isvariabletrue</a></div> <div class="signature">( <span class="arg_name">name</span>:string ) : boolean | nil</div></div><div class="body"><p class="desc">Returns a boolean value indicating whether the named Readline configuration variable is set to true (on), or nil if the variable name is not recognized.</p></div></div><hr/>
|
||
<div class="function"><div class="header"> <div class="name"><a name="rl.setmatches">rl.setmatches</a></div> <div class="signature">( <span class="arg_name">matches</span>:table, [<span class="arg_name">type</span>:string] ) : integer, boolean</div></div><div class="body"><p class="desc">Provides an alternative set of matches for the current word. This discards any matches that may have already been collected and uses <span class="arg">matches</span> for subsequent Readline completion commands until any action that normally resets the matches (such as moving the cursor or editing the input line).</p><p class="desc"> May only be used within a <code>luafunc:</code> key binding.</p><p class="desc"> The syntax is the same as for <a href="#builder:addmatches()">builder:addmatches()</a> with one addition: You can add a <code>"nosort"</code> key to the <span class="arg">matches</span> table to disable sorting the matches.</p><p class="desc"> <pre><code class="lua">local matches = {}<br/>matches["nosort"] = true<br/>rl.setmatches(matches)</code></pre></p><p class="desc"> This function can be used by a <code>luafunc:</code> key binding to provide matches based on some special criteria. For example, a key binding could collect numbers from the current screen buffer (such as issue numbers, commit hashes, line numbers, etc) and provide them to Readline as matches, making it convenient to grab a number from the screen and insert it as a command line argument.</p><p class="desc"> Match display filtering is also possible by using <a href="#clink.ondisplaymatches">clink.ondisplaymatches()</a> after setting the matches.</p><p class="desc"> <em>Example .inputrc key binding:</em> <pre><code class="plaintext">M-n: <span class="hljs-string">"luafunc:completenumbers"</span> <span class="hljs-comment"># Alt+N</span></code></pre></p><p class="desc"> <em>Example Lua function:</em></p><pre class="language-lua"><code>function completenumbers()
|
||
local _,last_luafunc = rl.getlastcommand()
|
||
if last_luafunc ~= "completenumbers" then
|
||
-- Collect numbers from the screen (minimum of three digits).
|
||
-- The numbers can be any base up to hexadecimal (decimal, octal, etc).
|
||
local matches = console.screengrab("[^%w]*(%w%w[%w]+)", "^%x+$")
|
||
-- They're already sorted by distance from the input line.
|
||
matches["nosort"] = true
|
||
rl.setmatches(matches)
|
||
end
|
||
|
||
rl.invokecommand("old-menu-complete")
|
||
end</code></pre></div></div><hr/>
|
||
<div class="function"><div class="header"> <div class="name"><a name="rl.setvariable">rl.setvariable</a></div> <div class="signature">( <span class="arg_name">name</span>:string, <span class="arg_name">value</span>:string ) : boolean</div></div><div class="body"><p class="desc">Temporarily overrides the named Readline configuration variable to the specified value. The return value reports whether it was successful, or is nil if the variable name is not recognized.</p><p class="desc"> <strong>Note:</strong> This does not write the value into a config file. Instead it updates the variable in memory, temporarily overriding whatever is present in any config files. When config files are reloaded, they may replace the value again.</p></div></div><hr/>
|
||
</div><div class="group"><h5 class="group_name"><a name="rl_buffer">rl_buffer</a></h5><div class="function"><div class="header"> <div class="name"><a name="rl_buffer:beginoutput">rl_buffer:beginoutput</a></div> <div class="signature">() : nil</div></div><div class="body"><p class="desc">Advances the output cursor to the next line after the Readline input buffer so that subsequent output doesn't overwrite the input buffer display.</p></div></div><hr/>
|
||
<div class="function"><div class="header"> <div class="name"><a name="rl_buffer:beginundogroup">rl_buffer:beginundogroup</a></div> <div class="signature">() : nil</div></div><div class="body"><p class="desc">Starts a new undo group. This is useful for grouping together multiple editing actions into a single undo operation.</p></div></div><hr/>
|
||
<div class="function"><div class="header"> <div class="name"><a name="rl_buffer:ding">rl_buffer:ding</a></div> <div class="signature">() : nil</div></div><div class="body"><p class="desc">Dings the bell. If the <code>bell-style</code> Readline variable is <code>visible</code> then it flashes the cursor instead.</p></div></div><hr/>
|
||
<div class="function"><div class="header"> <div class="name"><a name="rl_buffer:endundogroup">rl_buffer:endundogroup</a></div> <div class="signature">() : nil</div></div><div class="body"><p class="desc">Ends an undo group. This is useful for grouping together multiple editing actions into a single undo operation.</p><p class="desc"> Note: all undo groups are automatically ended when a key binding finishes execution, so this function is only needed if a key binding needs to create more than one undo group.</p></div></div><hr/>
|
||
<div class="function"><div class="header"> <div class="name"><a name="rl_buffer:getbuffer">rl_buffer:getbuffer</a></div> <div class="signature">() : string</div></div><div class="body"><p class="desc">Returns the current input line.</p></div></div><hr/>
|
||
<div class="function"><div class="header"> <div class="name"><a name="rl_buffer:getcursor">rl_buffer:getcursor</a></div> <div class="signature">() : integer</div></div><div class="body"><p class="desc">Returns the cursor position in the input line.</p></div></div><hr/>
|
||
<div class="function"><div class="header"> <div class="name"><a name="rl_buffer:getlength">rl_buffer:getlength</a></div> <div class="signature">() : integer</div></div><div class="body"><p class="desc">Returns the length of the input line.</p></div></div><hr/>
|
||
<div class="function"><div class="header"> <div class="name"><a name="rl_buffer:insert">rl_buffer:insert</a></div> <div class="signature">( <span class="arg_name">text</span>:string ) : nil</div></div><div class="body"><p class="desc">Inserts <span class="arg">text</span> at the cursor position in the input line.</p></div></div><hr/>
|
||
<div class="function"><div class="header"> <div class="name"><a name="rl_buffer:refreshline">rl_buffer:refreshline</a></div> <div class="signature">() : nil</div></div><div class="body"><p class="desc">Redraws the input line.</p></div></div><hr/>
|
||
<div class="function"><div class="header"> <div class="name"><a name="rl_buffer:remove">rl_buffer:remove</a></div> <div class="signature">( <span class="arg_name">from</span>:integer, <span class="arg_name">to</span>:integer ) : nil</div></div><div class="body"><p class="desc">Removes text from the input line starting at cursor position <span class="arg">from</span> through <span class="arg">to</span>.</p><p class="desc"> Note: the input line is UTF8, and removing only part of a multi-byte Unicode character may have undesirable results.</p></div></div><hr/>
|
||
<div class="function"><div class="header"> <div class="name"><a name="rl_buffer:setcursor">rl_buffer:setcursor</a></div> <div class="signature">( <span class="arg_name">cursor</span>:integer ) : integer</div></div><div class="body"><p class="desc">Sets the cursor position in the input line and returns the previous cursor position. <span class="arg">cursor</span> can be from 1 to rl_buffer:getlength().</p><p class="desc"> Note: the input line is UTF8, and setting the cursor position inside a multi-byte Unicode character may have undesirable results.</p></div></div><hr/>
|
||
</div><div class="group"><h5 class="group_name"><a name="settings">settings</a></h5><div class="function"><div class="header"> <div class="name"><a name="settings.add">settings.add</a></div> <div class="signature">( <span class="arg_name">name</span>:string, <span class="arg_name">default</span>:..., [<span class="arg_name">short_desc</span>:string], [<span class="arg_name">long_desc</span>:string] ) : boolean</div></div><div class="body"><p class="desc">Adds a setting to the list of Clink settings and includes it in <code>clink set</code>. The new setting is named <span class="arg">name</span> and has a default value <span class="arg">default</span> when the setting isn't explicitly set.</p><p class="desc"> The type of <span class="arg">default</span> determines what kind of setting is added: boolean, integer, and string values add the corresponding setting type. Or if the type is table then an enum setting is added: the table defines the accepted values, and the first value is the default value. Or if it's a string type and the name starts with "color." then a color setting is added.</p><p class="desc"> <span class="arg">name</span> can't be more than 32 characters.<br/> <span class="arg">short_desc</span> is an optional quick summary description and can't be more than 48 characters.<br/> <span class="arg">long_desc</span> is an optional long description.</p><pre class="language-lua"><code>settings.add("myscript.myabc", true, "Boolean setting")
|
||
settings.add("myscript.mydef", 100, "Number setting")
|
||
settings.add("myscript.myghi", "abc", "String setting")
|
||
settings.add("myscript.myjkl", {"x","y","z"}, "Enum setting")
|
||
settings.add("color.mymno", "bright magenta", "Color setting")</code></pre></div></div><hr/>
|
||
<div class="function"><div class="header"> <div class="name"><a name="settings.get">settings.get</a></div> <div class="signature">( <span class="arg_name">name</span>:string, [<span class="arg_name">descriptive</span>:boolean] ) : boolean or string or integer</div></div><div class="body"><p class="desc">Returns the current value of the <span class="arg">name</span> Clink setting.</p><p class="desc"> If it's a color setting and the optional <span class="arg">descriptive</span> parameter is true then the user friendly color name is returned.</p></div></div><hr/>
|
||
<div class="function"><div class="header"> <div class="name"><a name="settings.set">settings.set</a></div> <div class="signature">( <span class="arg_name">name</span>:string, <span class="arg_name">value</span>:string ) : boolean</div></div><div class="body"><p class="desc">Sets the <span class="arg">name</span> Clink setting to <span class="arg">value</span> and returns whether it was successful.</p></div></div><hr/>
|
||
</div><div class="group"><h5 class="group_name"><a name="string">string</a></h5><div class="function"><div class="header"> <div class="name"><a name="string.equalsi">string.equalsi</a></div> <div class="signature">( <span class="arg_name">a</span>:string, <span class="arg_name">b</span>:string ) : boolean</div></div><div class="body"><p class="desc">Performs a case insensitive comparison of the strings with international linguistic awareness. This is more efficient than converting both strings to lowercase and comparing the results.</p></div></div><hr/>
|
||
<div class="function"><div class="header"> <div class="name"><a name="string.explode">string.explode</a></div> <div class="signature">( <span class="arg_name">text</span>:string, [<span class="arg_name">delims</span>:string], [<span class="arg_name">quote_pair</span>:string] ) : table</div></div><div class="body"><p class="desc">Splits <span class="arg">text</span> delimited by <span class="arg">delims</span> (or by spaces if not provided) and returns a table containing the substrings.</p><p class="desc"> The optional <span class="arg">quote_pair</span> can provide a beginning quote character and an ending quote character. If only one character is provided it is used as both a beginning and ending quote character.</p></div></div><hr/>
|
||
<div class="function"><div class="header"> <div class="name"><a name="string.hash">string.hash</a></div> <div class="signature">( <span class="arg_name">text</span>:string ) : integer</div></div><div class="body"><p class="desc">Returns a hash of the input <span class="arg">text</span>.</p></div></div><hr/>
|
||
<div class="function"><div class="header"> <div class="name"><a name="string.matchlen">string.matchlen</a></div> <div class="signature">( <span class="arg_name">a</span>:string, <span class="arg_name">b</span>:string ) : integer</div></div><div class="body"><p class="desc">Returns how many characters match at the beginning of the strings, or -1 if the entire strings match. This respects the <code>match.ignore_case</code> and <code>match.ignore_accents</code> Clink settings.</p><pre class="language-lua"><code>string.matchlen("abx", "a") -- returns 1
|
||
string.matchlen("abx", "aby") -- returns 2
|
||
string.matchlen("abx", "abx") -- returns -1</code></pre></div></div><hr/>
|
||
</div><div class="group"><h5 class="group_name"><a name="word_classifications">word_classifications</a></h5><div class="function"><div class="header"> <div class="name"><a name="word_classifications:applycolor">word_classifications:applycolor</a></div> <div class="signature">( <span class="arg_name">start</span>:integer, <span class="arg_name">length</span>:integer, <span class="arg_name">color</span>:string, [<span class="arg_name">overwrite</span>:boolean] ) : nil</div></div><div class="body"><p class="desc">Applies an ANSI <a href="https://en.wikipedia.org/wiki/ANSI_escape_code#SGR">SGR escape code</a> to some characters in the input line.</p><p class="desc"> <span class="arg">start</span> is where to begin applying the SGR code.</p><p class="desc"> <span class="arg">length</span> is the number of characters to affect.</p><p class="desc"> <span class="arg">color</span> is the SGR parameters sequence to apply (for example <code>"7"</code> is the code for reverse video, which swaps the foreground and background colors).</p><p class="desc"> By default the color is applied to the characters even if some of them are already colored. But if <span class="arg">overwrite</span> is <code>false</code> each character is only colored if it hasn't been yet.</p><p class="desc"> See <a href="#classifywords">Coloring The Input Text</a> for more information.</p></div></div><hr/>
|
||
<div class="function"><div class="header"> <div class="name"><a name="word_classifications:classifyword">word_classifications:classifyword</a></div> <div class="signature">( <span class="arg_name">word_index</span>:integer, <span class="arg_name">word_class</span>:string, [<span class="arg_name">overwrite</span>:boolean] ) : nil</div></div><div class="body"><p class="desc">This classifies the indicated word so that it can be colored appropriately.</p><p class="desc"> The <span class="arg">word_class</span> is one of the following codes:</p><p class="desc"> <table> <tr><th>Code</th><th>Classification</th><th>Clink Color Setting</th></tr> <tr><td><code>"a"</code></td><td>Argument; used for words that match a list of preset argument matches.</td><td><code>color.arg</code> or <code>color.input</code></td></tr> <tr><td><code>"c"</code></td><td>Shell command; used for CMD command names.</td><td><code>color.cmd</code></td></tr> <tr><td><code>"d"</code></td><td>Doskey alias.</td><td><code>color.doskey</code></td></tr> <tr><td><code>"f"</code></td><td>Flag; used for flags that match a list of preset flag matches.</td><td><code>color.flag</code></td></tr> <tr><td><code>"o"</code></td><td>Other; used for file names and words that don't fit any of the other classifications.</td><td><code>color.input</code></td></tr> <tr><td><code>"n"</code></td><td>None; used for words that aren't recognized as part of the expected input syntax.</td><td><code>color.unexpected</code></td></tr> <tr><td><code>"m"</code></td><td>Prefix that can be combined with another code (for the first word) to indicate the command has an argmatcher (e.g. <code>"mc"</code> or <code>"md"</code>).</td><td><code>color.argmatcher</code> or the other code's color</td></tr> </table></p><p class="desc"> By default the classification is applied to the word even if the word has already been classified. But if <span class="arg">overwrite</span> is <code>false</code> the word is only classified if it hasn't been yet.</p><p class="desc"> See <a href="#classifywords">Coloring The Input Text</a> for more information.</p></div></div><hr/>
|
||
</div><div class="group"><h5 class="group_name"><a name="[other]">[other]</a></h5><div class="function"><div class="header"> <div class="name"><a name="rl_state">rl_state</a></div> <div class="signature">table variable</div></div><div class="body deprecated"><p class="desc"><strong>Deprecated; don't use this.</strong> See <a href="#line">line</a> for more information.</p><p class="desc">This is an obsolete global variable that was set while running match generators. It has been superseded by the <a href="#line">line</a> type parameter passed into match generator functions when using the new <a href="#clink.generator">clink.generator</a> API.</p></div></div><hr/>
|
||
</div>
|
||
</div>
|
||
<div class="section" id="changes">
|
||
<h1 id="changes">Changes</h1>
|
||
<h2 id="releases-from-chrisant996clink-fork">Releases from <a href="https://github.com/chrisant996/clink">chrisant996/clink</a> fork</h2>
|
||
<h3 id="v129">v1.2.9</h3>
|
||
<ul>
|
||
<li>Added detection for possible antivirus interference when injecting Clink.</li>
|
||
<li>Ignore duplicate scripts paths when loading scripts.</li>
|
||
<li>Fixed <a href="https://github.com/chrisant996/clink/issues/118">#118</a>; inputrc is not read from state directory (regression introduced in v1.0.0).</li>
|
||
</ul>
|
||
<h3 id="v128">v1.2.8</h3>
|
||
<ul>
|
||
<li>Fixed <code>...\</code> or <code>.../</code> to change directories (path separator after several dots).</li>
|
||
<li>Fixed <code>/dirname/</code> to change directories (forward slashes when a directory is the only thing in the input line).</li>
|
||
<li>Fixed <a href="https://github.com/chrisant996/clink/issues/114">#114</a>; "Clink already loaded in process" error when autorun is installed for both Current User and All Users.</li>
|
||
<li>Fixed <a href="https://github.com/chrisant996/clink/issues/113">#113</a>; forward slash translation didn't work with the <code>cd</code> command.</li>
|
||
</ul>
|
||
<h3 id="v127">v1.2.7</h3>
|
||
<ul>
|
||
<li>Fixed <a href="https://github.com/chrisant996/clink/issues/113">#113</a>; <code>clink.slash_translation()</code> had been removed (regression introduced in v1.0.0).<ul>
|
||
<li>The new <code>match.translate_slashes</code> setting controls the default behavior for slash translation for completion matches.</li>
|
||
<li>The new <code>clink.translateslashes()</code> API can override slash translation for completion matches (and <code>clink.slash_translation()</code> is supported for backward compatibility).</li>
|
||
</ul>
|
||
</li>
|
||
</ul>
|
||
<h3 id="v126">v1.2.6</h3>
|
||
<ul>
|
||
<li>Fixed tilde expansion for directory by itself; now <code>~\</code> can change the working directory to the <code>~</code> directory.</li>
|
||
<li>Fixed pagination when displaying completions that take more than 1 line to display.</li>
|
||
<li>Fixed inserting directory match completions when a Lua script didn't include a trailing path separator in the directory match.</li>
|
||
<li>Fixed <a href="https://github.com/chrisant996/clink/issues/111">#111</a>; <code>..</code> completion is different from bash (regression introduced in v1.0.0).</li>
|
||
</ul>
|
||
<h3 id="v125">v1.2.5</h3>
|
||
<ul>
|
||
<li>Added <code>os.expandenv()</code> function to expand environment variables in a string.</li>
|
||
<li>Added <code>console.cellcount()</code> function to count the cells a string will use when displayed.</li>
|
||
<li>Added <code>console.plaintext()</code> function to remove ANSI escape codes from a string.</li>
|
||
<li>Clink now sets <code>%=clink.bin%</code> that points to the Clink binaries directory. This can be particularly useful for a portable installation of Clink so that scripts can find the Clink binaries directory and construct relative paths to other nearby files.</li>
|
||
<li>Clean up column alignment in <code>--help</code> texts.</li>
|
||
<li>Fixed <code>history.sticky_search</code> with anchored history search.</li>
|
||
<li>Fixed <code>clink inject --profile</code> to use correct log file name while initially injecting.</li>
|
||
<li>Fixed Clink autorun to be more compatible with Cmder (<a href="https://github.com/cmderdev/cmder/issues/2536">Cmder #2536</a>).</li>
|
||
</ul>
|
||
<h3 id="v124">v1.2.4</h3>
|
||
<ul>
|
||
<li>Added support for <kbd>Shift</kbd>+<kbd>Arrows</kbd> to select text and typing to replace selected text.</li>
|
||
<li>Added optional argument to <code>word_classifications:classifyword()</code> and <code>word_classifications:applycolor()</code> to allow only applying color where another color hasn't yet been applied.</li>
|
||
<li>Fixed first <kbd>Up</kbd> after reusing a history line so that it gets the reused history line, rather than getting the previous history line.</li>
|
||
<li>Fixed <code>add-history</code> command to not add blank lines to history.</li>
|
||
<li>Fixed <code>rl.setmatches()</code> (regression introduced in v1.1.26).</li>
|
||
<li>Fixed input coloring for <code>clink set</code> and any color setting name (regression introduced in v1.2).</li>
|
||
<li>Fixed potential crash with <code>clink history --session</code>.</li>
|
||
<li>Fixed <kbd>Ctrl</kbd>+<kbd>D</kbd> when <code>cmd.ctrld_exits</code> is disabled; it didn't exit, but it did still discard the input line and start a new prompt.</li>
|
||
<li>Fixed <a href="https://github.com/chrisant996/clink/issues/107">#107</a>; autorun reports inject failures (regression introduced in v1.2.3).</li>
|
||
<li>Fixed <a href="https://github.com/chrisant996/clink/issues/106">#106</a>; history missing <code>--bare</code> option (regression introduced in v1.2.3).</li>
|
||
</ul>
|
||
<h3 id="v123">v1.2.3</h3>
|
||
<ul>
|
||
<li>Added <code>history.sticky_search</code> setting: when enabled, reusing a history line does not add the reused line to the end of the history, and it leaves the history search position on the reused line so next/prev history can continue from there (e.g. replaying commands via <kbd>Up</kbd> several times then <kbd>Enter</kbd>, <kbd>Down</kbd>, <kbd>Enter</kbd>, etc).</li>
|
||
<li>Added failure reporting and logging when <code>clink inject</code> fails.</li>
|
||
<li>Added <code>--unique</code> flag for use with <code>clink history compact --unique</code> to remove duplicate entries from the history list.</li>
|
||
<li>The <code>clink-popup-complete</code> command now matches wildcards.</li>
|
||
<li>Restored the <kbd>Ctrl</kbd>+<kbd>Alt</kbd>+<kbd>U</kbd> key binding from v0.4.9 (moves the current working directory up one level).</li>
|
||
<li>Fixed searching for inputrc files to also search in the profile directory (regression introduced in v1.0.0).</li>
|
||
<li>Fixed incremental search in the History popup list to search in reverse order (bottom to top).</li>
|
||
<li>Fixed <code>clink-popup-history</code> to set the history search position like other history search commands do, so that it plays well with the <code>history.sticky_search</code> setting.</li>
|
||
</ul>
|
||
<h3 id="v122">v1.2.2</h3>
|
||
<ul>
|
||
<li>Added <code>%CLINK_HISTORY_LABEL%</code> environment variable to use a different master history file (fixes <a href="https://github.com/chrisant996/clink/issues/99">#99</a>).</li>
|
||
</ul>
|
||
<h3 id="v121">v1.2.1</h3>
|
||
<ul>
|
||
<li>Added Troubleshooting Tips section in the documentation.</li>
|
||
<li>Added backward compatibility for <code>clink set</code> with v0.4.9. Old setting names and values are not documented, but are automatically mapped to the appropriate new setting(s). This was done so that suggestions in old web sites and posts can usually continue to work, to reduce confusion and support burden.</li>
|
||
<li>Fixed <a href="https://github.com/chrisant996/clink/issues/97">#97</a>; VS2017 error C2039: 'min': is not a member of 'std'.</li>
|
||
<li>Fixed <a href="https://github.com/chrisant996/clink/issues/96">#96</a>; wrong setting string (the name of a setting was accidentally truncated).</li>
|
||
<li>Fixed some slightly inaccurate/incomplete migration from old settings to new settings.</li>
|
||
</ul>
|
||
<h3 id="v12">v1.2</h3>
|
||
<ul>
|
||
<li>First official release from <a href="https://github.com/chrisant996/clink">chrisant996/clink</a> fork.</li>
|
||
</ul>
|
||
<h3 id="v1149">v1.1.49</h3>
|
||
<ul>
|
||
<li>Added <code>clink.classifier()</code> to enable coloring the input line independently from argmatchers.</li>
|
||
<li>Added <code>word_classifications:applycolor()</code> to apply SGR escape codes anywhere in the input line.</li>
|
||
<li>Removed <code>word_classifications:iswordclassified()</code>.</li>
|
||
<li>Fixed the Product Version string in the binary file version resources.</li>
|
||
</ul>
|
||
<h3 id="v1148">v1.1.48</h3>
|
||
<ul>
|
||
<li>Added <code>clink.getansihost()</code> function to get Clink's best guess who will process ANSI escape codes (can be useful for avoiding 256 bit and 24 bit color codes, for example).</li>
|
||
<li>Added detection for being hosted in ConsoleZ.</li>
|
||
<li>Fixed <a href="https://github.com/chrisant996/clink/issues/20">#20</a>; <code>set /p VAR=""</code> shows the normal command prompt text instead of empty prompt text.</li>
|
||
</ul>
|
||
<h3 id="v1147">v1.1.47</h3>
|
||
<ul>
|
||
<li>Added default key binding for <kbd>Ctrl</kbd>+<kbd>Space</kbd> to invoke <code>old-menu-complete</code>, which is the most similar to CMD's standard <kbd>Tab</kbd> behavior.</li>
|
||
<li>Fixed <code>search-ignore-case</code> config variable to be on by default.</li>
|
||
</ul>
|
||
<h3 id="v1146">v1.1.46</h3>
|
||
<ul>
|
||
<li>Added <code>rl.setvariable()</code> to temporarily override the value of a Readline config variable.</li>
|
||
<li>The completion commands now also expand tilde by itself (<code>~</code>), in addition to tilde followed by a path separator (<code>~\etc</code>).</li>
|
||
<li>Fixed <a href="https://github.com/chrisant996/clink/issues/94">#94</a>; setting <code>history.save</code> to False also disables interactive history in subsequent sessions.</li>
|
||
</ul>
|
||
<h3 id="v1145">v1.1.45</h3>
|
||
<ul>
|
||
<li>Fixed <a href="https://github.com/chrisant996/clink/issues/93">#93</a>; stdout is sometimes broken by Cmder init.bat.</li>
|
||
</ul>
|
||
<h3 id="v1144">v1.1.44</h3>
|
||
<ul>
|
||
<li>Added <code>clink.getsession()</code>.</li>
|
||
<li>Added <code>%CLINK_NOAUTORUN%</code> which overrides automatic inject when Clink is installed for autorun.</li>
|
||
<li>Fixed <a href="https://github.com/chrisant996/clink/issues/92">#92</a>; <code>clink-popup-history</code> and similar commands not working with ConEmu and Cmder (regression introduced in v1.1.25).</li>
|
||
</ul>
|
||
<h3 id="v1143">v1.1.43</h3>
|
||
<ul>
|
||
<li>Added <code>clink history --diag</code> flag that prints diagnostic information while performing history operations.</li>
|
||
<li>Minor optimization in <code>clink history</code> when printing the full list of history items.</li>
|
||
<li>Fixed <code>clink history compact</code> so it actually performs compaction.</li>
|
||
</ul>
|
||
<h3 id="v1142">v1.1.42</h3>
|
||
<ul>
|
||
<li>Added <code>clink history --bare</code> flag to omit history item numbers.</li>
|
||
<li>Added several Lua functions:<ul>
|
||
<li><code>io.popenrw()</code> is like <code>io.popen()</code>, but returns both a read file handle and a write file handle (see documentation for important usage warning).</li>
|
||
<li><code>os.createtmpfile()</code> creates a unique named temporary file, with control over the prefix and suffix and path.</li>
|
||
<li><code>os.getfullpathname()</code> to get the full path name for a file.</li>
|
||
<li><code>os.getlongpathname()</code> to get the long path name for a file.</li>
|
||
<li><code>os.getshortpathname()</code> to get the 8.3 short path name (if available) for a file.</li>
|
||
</ul>
|
||
</li>
|
||
<li>Improved argument validation for Clink's Lua APIs. This could expose bugs in existing scripts, so there is also a <code>lua.strict</code> setting that can be disabled to revert back to loose argument validation.</li>
|
||
<li>Updated documentation.</li>
|
||
<li>Fixed <code>clink history compact</code> so that it forces compaction as intended.</li>
|
||
<li>Fixed completion for <code>clink set</code> so that filename completion works in string settings.</li>
|
||
<li>Fixed backwards return value from <code>rl.invokecommand()</code>.</li>
|
||
<li>Fixed console input/output modes across <code>luafunc:</code> key bindings, in case the Lua functions spawn a process that alters the console mode without restoring it.</li>
|
||
</ul>
|
||
<h3 id="v1141">v1.1.41</h3>
|
||
<ul>
|
||
<li>Added <code>terminal.adjust_cursor_style</code> setting as a workaround to avoid interfering with the Windows 10 Cursor Shape console setting. There are several trade-offs, though.</li>
|
||
<li>Added <code>rl_buffer:refreshline()</code> function to redraw the input line, e.g. in case something has written over it.</li>
|
||
<li>Added <code>os.getpid()</code> function to get the process ID, intended mainly to help salt unique resource names.</li>
|
||
<li>Added <code>clink.onfiltermatches()</code> so scripts can register a callback function to run after Clink generates matches and before it displays them.</li>
|
||
</ul>
|
||
<h3 id="v1140">v1.1.40</h3>
|
||
<ul>
|
||
<li>Added a group of <code>clink-complete-numbers</code> commands that do completion for numbers from the console screen, bound to <kbd>Ctrl</kbd>+<kbd>Alt</kbd>+<kbd>N</kbd> by default.</li>
|
||
<li>Added <code>rl.getlastcommand()</code> function that returns the name of the last command invoked by key bindings.</li>
|
||
<li>Fixed sort order in <kbd>Alt</kbd>+<kbd>H</kbd> for the newly supported key bindings (that were added in v1.1.39).</li>
|
||
<li>Fixed <kbd>Ctrl</kbd>+<kbd>Space</kbd> (regression introduced in v1.1.39).</li>
|
||
<li>Fixed various <kbd>Ctrl</kbd>+<kbd>Shift</kbd>+<kbd>whatever</kbd> combinations (regression introduced in v1.1.39).</li>
|
||
<li>Fixed <code>rl.setmatches()</code> when the input line is not empty and <code>clink.colorize_input</code> is enabled.</li>
|
||
</ul>
|
||
<h3 id="v1139">v1.1.39</h3>
|
||
<ul>
|
||
<li>Added support for many more key bindings, such as <kbd>Ctrl</kbd>+<kbd>Shift</kbd>+Letter keys.</li>
|
||
<li>Added <code>terminal.differentiate_keys</code> setting that when enabled allows binding <kbd>Ctrl</kbd> + <kbd>H</kbd> or <kbd>I</kbd> or <kbd>M</kbd> or <kbd>[</kbd> separately from <kbd>Backspace</kbd>, <kbd>Tab</kbd>, <kbd>Return</kbd>, or <kbd>Escape</kbd>.</li>
|
||
<li>Removed <code>terminal.modify_other_keys</code> setting and made it always enabled.</li>
|
||
<li>Changed <code>terminal.use_altgr_substitute</code> to be disabled by default so that <kbd>Ctrl</kbd>+<kbd>Alt</kbd> key bindings can work by default on keyboards with <kbd>AltGr</kbd>.</li>
|
||
<li>Changed output from <code>clink echo</code> so it's directly usable in the inputrc files.</li>
|
||
<li>Fixed <code>terminal.use_altgr_substitute</code> to only affect <kbd>AltGr</kbd> substitute key combinations (it had always broken the <kbd>RightAlt</kbd> key in general on other keyboard layouts).</li>
|
||
<li>Fixed a benign issue with the console input mode in <code>clink echo</code>.</li>
|
||
</ul>
|
||
<h3 id="v1138">v1.1.38</h3>
|
||
<ul>
|
||
<li>Fixed <a href="https://github.com/chrisant996/clink/issues/84">#84</a>; added <code>terminal.use_altgr_substitute</code> setting.</li>
|
||
<li>Fixed <a href="https://github.com/chrisant996/clink/issues/80">#80</a>; clink.log is not deleted when Cmder injects Clink.</li>
|
||
</ul>
|
||
<h3 id="v1137">v1.1.37</h3>
|
||
<ul>
|
||
<li>Fixed copy to clipboard (it never cleared the clipboard!).</li>
|
||
<li>Fixed <a href="https://github.com/chrisant996/clink/issues/82">#82</a>; added two new <code>clink.paste_crlf</code> modes: <code>ampersand</code> replaces newlines with ampersands, and <code>crlf</code> pastes newlines as-is and executes any commands ending in a newline.</li>
|
||
<li>Fixed <a href="https://github.com/chrisant996/clink/issues/69">#69</a>; space in the prompt disappears after enter echo: added support for CJK codepages.</li>
|
||
</ul>
|
||
<h3 id="v1136">v1.1.36</h3>
|
||
<ul>
|
||
<li>Fixed <a href="https://github.com/chrisant996/clink/issues/79">#79</a>; Issue with United States - international keyboard layout (regression introduced in v1.1.0).</li>
|
||
<li>Fixed <a href="https://github.com/chrisant996/clink/issues/78">#78</a>; crash when history file contains a line longer than 8192 characters (regression introduced in v1.1.2-alpha).</li>
|
||
</ul>
|
||
<h3 id="v1135">v1.1.35</h3>
|
||
<ul>
|
||
<li>Fixed when the <code>mark-directories</code> inputrc variable is <code>off</code> (regression introduced in v1.1.1-alpha).</li>
|
||
<li>Fixed Lua reading from stdin, especially in the Lua debugger (regression introduced in v1.1.25).</li>
|
||
<li>Fixed exponential cost performance bug in Readline when removing duplicate matches.</li>
|
||
</ul>
|
||
<h3 id="v1134">v1.1.34</h3>
|
||
<ul>
|
||
<li>Fixed copying to clipboard (CF_UNICODETEXT was put on the clipboard correctly, but CF_TEXT was empty and should have been omitted to let Windows automatically convert it from the Unicode text).</li>
|
||
</ul>
|
||
<h3 id="v1133">v1.1.33</h3>
|
||
<ul>
|
||
<li>Make the "replacing arglink" warning message a little more informative, and write a lua traceback to the Clink log file.</li>
|
||
<li>Fixed <a href="https://github.com/chrisant996/clink/issues/77">#77</a>; with ConsoleZ scrolling does not always work.</li>
|
||
<li>Fixed <a href="https://github.com/chrisant996/clink/issues/76">#76</a>; cannot <code>cd</code> up multiple directories normally.</li>
|
||
</ul>
|
||
<h3 id="v1132">v1.1.32</h3>
|
||
<ul>
|
||
<li>Added support for non-standard escape codes to set the window title or print environment variables. Depending on the <code>terminal.emulation</code> setting, the behavior is slightly different. When <code>emulate</code> Clink processes the escape codes. When <code>native</code> with ConEmu (and Clink) the escape codes are passed to ConEmu, except that Clink processes the environment variable codes in prompt strings. When <code>native</code> with other terminals, Clink preprocesses the title and environment variable escape codes in prompt strings, but passes the escape codes to the terminal outside of prompt strings.</li>
|
||
<li>Fixed <a href="https://github.com/chrisant996/clink/issues/67">#67</a>; AutoRun interferes with Cmder.</li>
|
||
</ul>
|
||
<h3 id="v1131">v1.1.31</h3>
|
||
<ul>
|
||
<li>Fixed <a href="https://github.com/chrisant996/clink/issues/74">#74</a>; clink gets confused by non-standard ConEmu escape codes.</li>
|
||
<li>Fixed <a href="https://github.com/chrisant996/clink/issues/73">#73</a>; <code>exec.space_prefix</code> and other settings defined in Lua scripts don't take effect until second input line (regression introduced in v1.1.4).</li>
|
||
</ul>
|
||
<h3 id="v1130">v1.1.30</h3>
|
||
<ul>
|
||
<li>Fixed history compacting on x86 (regression introduced in v1.1.2-alpha).</li>
|
||
</ul>
|
||
<h3 id="v1129">v1.1.29</h3>
|
||
<ul>
|
||
<li>Added <code>clink installscripts</code> and <code>clink uninstallscripts</code> to make it easy for package managers like Scoop to install/uninstall script packages for use with Clink. The installed script paths are stored in the registry for the current user.</li>
|
||
<li>Fixed <code>bold</code> vs <code>bright</code> colors to more accurately follow generally accepted ANSI escape code conventions:<ul>
|
||
<li>Renamed <code>dim</code> to <code>nobold</code> for clarity (though <code>dim</code> is still recognized for backward compatibility).</li>
|
||
<li><code>bold</code> adds intensity to a non-intense color (e.g. <code>cyan</code> which is 36).</li>
|
||
<li><code>nobold</code> removes intensity added by <code>bold</code> (e.g. <code>1;36</code> becomes <code>36</code>), but does not remove intensity from an explicit intense color (such as <code>bright cyan</code> which is <code>96</code>).</li>
|
||
</ul>
|
||
</li>
|
||
<li>Fixed support for <code>--file=</code> flags in argmatchers.</li>
|
||
<li>Fixed match display filtering on the first try for a word (regression introduced in v1.1.19).</li>
|
||
<li>Fixed the <code>clink --profile</code> flag (regression introduced in v1.1.10).</li>
|
||
<li>Fixed <code>clink info</code> to accurately report the script dirs (it didn't account for the <code>clink.path</code> setting correctly).</li>
|
||
</ul>
|
||
<h3 id="v1128">v1.1.28</h3>
|
||
<ul>
|
||
<li>Renamed the <code>log.rl_terminal</code> setting to <code>debug.log_terminal</code>; it has already been repeatedly very useful in multiple was since it was added, so it stays.</li>
|
||
<li>Fixed <a href="https://github.com/chrisant996/clink/issues/70">#70</a>; ctrl+c not working (regression introduced in v1.1.25).</li>
|
||
</ul>
|
||
<h3 id="v1127">v1.1.27</h3>
|
||
<ul>
|
||
<li>Added <code>color.argmatcher</code> setting which, when set, is used to color a command name if it has an associated argmatcher (this supersedes <code>color.cmd</code>, <code>color.doskey</code>, and <code>color.input</code>). By default it's not set.</li>
|
||
<li>Added <code>log.rl_terminal</code> setting which logs all terminal input and output for Readline (this setting may be renamed or removed in the future).</li>
|
||
</ul>
|
||
<h3 id="v1126">v1.1.26</h3>
|
||
<ul>
|
||
<li>Added <code>rl.invokecommand()</code> which can invoke a Readline command from inside a "luafunc:" key binding.</li>
|
||
<li>Added <code>rl.setmatches()</code> which can override match completions from inside a "luafunc:" key binding.</li>
|
||
<li>Worked around UTF8 key binding problem with Readline which had been causing some meta key bindings (M-x, M-C-x, etc) to sometimes produce garbled key bindings and garbled entries in <code>clink-show-help</code> (<kbd>Alt</kbd>+<kbd>H</kbd>).</li>
|
||
<li>Fixed crash if "luafunc:" key binding macro refers to a symbol that doesn't exist.</li>
|
||
</ul>
|
||
<h3 id="v1125">v1.1.25</h3>
|
||
<ul>
|
||
<li>Added <code>clink-find-conhost</code> command that, when in a default (conhost) console window, is equivalent to picking "Find..." from the system menu.</li>
|
||
<li>Added <code>clink-mark-conhost</code> command that, when in a default (conhost) console window, is equivalent to picking "Mark" from the system menu.</li>
|
||
<li><code>clink-copy-word</code> now copies the current word by default, but copies the nth word if a numeric argument is entered (see "Readline Arguments" in the Readline manual).</li>
|
||
<li>Fixed match display filtering to not exceed the screen width (regression introduced in v1.1.12).</li>
|
||
<li>Fixed multi-key sequences; in some cases it could get confused about whether an input key is part of a multi-key binding sequence (regression introduced in v1.1.1-alpha).</li>
|
||
<li>Fixed stray input processing by conhost (holding <kbd>Ctrl</kbd>+<kbd>A</kbd> or <kbd>Ctrl</kbd>+<kbd>F</kbd> or etc could accidentally trigger conhost's shortcut keys).</li>
|
||
<li>Fixed popup window location and size when using Windows Terminal.</li>
|
||
<li>Fixed input coloring after <code>operate-and-get-next</code>; also fixes brief flicker of incorrect coloring whenever the input line is modified.</li>
|
||
</ul>
|
||
<h3 id="v1124">v1.1.24</h3>
|
||
<ul>
|
||
<li><code>auto</code> for <code>terminal.emulation</code> now uses native VT support on Windows 10 build 15063 and higher, unless the HKCU\Console\ForceV2 regkey is 0.</li>
|
||
<li>Special quote handling now enables <code>"dir\"fi</code> to complete to <code>"dir\file"</code>. CMD simply strips quotes during completion, and now Clink behaves similarly.</li>
|
||
<li><strong>Breaking Change:</strong> <code>line:getword()</code> and <code>line:getendword()</code> now strip quotes from the word. This should generally automagically make existing match generators work even with embedded quotes, but there's a chance that some match generator might need to be updated. This seems like a reasonable compromise, given the general benefit purchased by this breaking change.</li>
|
||
<li><code>os:globdirs()</code> and <code>os:globfile()</code> strip quotes from the <span class="arg">globpattern</span> in order to behave more like CMD. Embedded quotes are nonsensical and the intended interpretation is clear, so the APIs now help out with that.</li>
|
||
<li>Fixed <a href="https://github.com/chrisant996/clink/issues/66">#66</a>; crash when injecting into 32 bit cmd (regression introduced in v1.1.21).</li>
|
||
<li>Fixed <a href="https://github.com/chrisant996/clink/issues/64">#64</a>; wrong cursor position when PROMPT contains BEL character.</li>
|
||
<li>Fixed <a href="https://github.com/chrisant996/clink/issues/62">#62</a>; argmatchers should color <code>-x:"foo"</code> as a flag if <code>-x:</code> is a flag.</li>
|
||
<li>Fixed <a href="https://github.com/chrisant996/clink/issues/61">#61</a>; argmatchers should not handle completion for text immediately following <code>-flag:</code>. Instead it always uses file completion. A custom generator can be used to override that behavior.</li>
|
||
<li>Fixed <a href="https://github.com/chrisant996/clink/issues/60">#60</a>; completion fails with multiple slashes.</li>
|
||
<li>Fixed completion in some circumstances. Readline and Clink didn't always agree on where the word breaks were; now Clink always tells Readline where the word breaks are (so that completion, input colorization, and lua scripts can all work properly and consistently).</li>
|
||
<li>Fixed 256 color ANSI codes.</li>
|
||
</ul>
|
||
<h3 id="v1123">v1.1.23</h3>
|
||
<ul>
|
||
<li>Fixed <a href="https://github.com/chrisant996/clink/issues/57">#57</a>; slashes not normalized in some cases.</li>
|
||
<li>Fixed <a href="https://github.com/chrisant996/clink/issues/45">#45</a>; interaction between <code>history.dupe_mode</code>=<code>erase_prev</code> and <code>history.shared</code>=<code>false</code>.</li>
|
||
<li>Fixed <code>menu-complete-wraparound</code> when off and there's only 1 match.</li>
|
||
</ul>
|
||
<h3 id="v1122">v1.1.22</h3>
|
||
<ul>
|
||
<li>Added <code>menu-complete-wraparound</code> (on by default) that controls whether completion commands wrap around when cycling past an end (affects popup windows as well).</li>
|
||
<li>Fixed match completion getting stuck (regression introduced in v1.1.19).</li>
|
||
<li>Fixed active mark region so it gets deactivated appropriately (it wasn't hooked up fully for Readline's callback mode, which is the mode Clink uses).</li>
|
||
<li>Fixed <code>clink-show-help</code> (<kbd>Alt</kbd>+<kbd>H</kbd>) so it's able to list <code>C-@</code> bindings.</li>
|
||
<li>Fixed inconsistent mark color.</li>
|
||
</ul>
|
||
<h3 id="v1121">v1.1.21</h3>
|
||
<ul>
|
||
<li>Added <code>clink.oninject()</code> so scripts can register a callback function to run when Clink is injected into CMD.</li>
|
||
<li>Added <code>console.linehascolor()</code> function that returns whether the specified line contains any of the specified colors.</li>
|
||
<li>Added <code>console.findprevline()</code> and <code>console.findnextline()</code> functions that can search backwards or forwards for text and/or colors in the screen buffer. Regular expressions may be used.</li>
|
||
<li>Fixed doskey alias parsing for match generators and input line coloring (Clink had been using slightly different parsing rules than CMD does).</li>
|
||
<li>Fixed the "-- More --" prompt while listing key bindings; <kbd>Esc</kbd> didn't quit, and unexpected keys weren't ignored.</li>
|
||
</ul>
|
||
<h3 id="v1120">v1.1.20</h3>
|
||
<ul>
|
||
<li>Now you can bind Lua functions to keys via "luafunc:" macros! Added new <code>rl_buffer</code> type that gets passed to the Lua function.</li>
|
||
<li>Added a group of <code>console</code> Lua APIs intended mainly for use by Lua function key bindings (e.g. <code>console.scroll()</code>).</li>
|
||
<li>Added <code>string.equalsi()</code> function that performs a case insensitive UTF8 comparison of two strings.</li>
|
||
<li>Added <code>string.matchlen()</code> function that compares two UTF8 strings and returns how many characters match at the beginning, or -1 if the entire strings match. It respects the <code>match.ignore_case</code> and <code>match.ignore_accents</code> settings.</li>
|
||
<li>Added <code>path.toparent()</code> function that adjust the input string by moving up one directory level.</li>
|
||
<li>Added <code>clink.onendedit()</code> so scripts can register a callback function to run when editing finishes (e.g. <kbd>Enter</kbd> is pressed). If desired, the function can even change the input text. This is very powerful, and should be used carefully.</li>
|
||
<li>Changed <code>os.getbatterystatus()</code> to return a table with the battery status details, rather than four separate return values.</li>
|
||
<li>Fixed the <code>doskey.enhanced</code> setting to not expand doskey aliases when preceded by a space. However, a doskey alias after a <code>&</code> or <code>|</code> command separator needs to be preceded by two spaces to avoid expanding it. That's so <code>alias & alias</code> expands both, and <code> alias & alias</code> expands neither; while the rules are more complicated to explain, they make more sense visually.</li>
|
||
<li>Fixed environment variable completion (regression introduced in v1.1.19).</li>
|
||
<li>Fixed Cmder startup (regression introduced in v1.1.17). Cmder expects to be able to replace Clink v0.4.9's clink.lua file, but there is no such thing anymore in newer versions of Clink. To be properly backwardly compatible with Clink v0.4.9 requires loading clink.lua (if it exists) from the first script directory listed by <code>clink info</code>, and ignoring clink.lua files in all other script directories.</li>
|
||
</ul>
|
||
<h3 id="v1119">v1.1.19</h3>
|
||
<ul>
|
||
<li>Improved responsiveness while typing: matches are collected only on demand, instead of always while typing. This makes it possible to always support match completion for UNC paths.</li>
|
||
<li>Fixed <a href="https://github.com/chrisant996/clink/issues/50">#50</a>; <kbd>Alt</kbd>+<kbd>H</kbd> could warn about likely mistakes in key bindings.</li>
|
||
</ul>
|
||
<h3 id="v1118">v1.1.18</h3>
|
||
<ul>
|
||
<li>The input text now has context sensitive coloring based on the argmatchers. It's on by default and can be turned off with <code>clink set clink.colorize_input false</code>.</li>
|
||
<li>Updated the Readline library to 8.1.</li>
|
||
<li>Terminal emulation now supports the audible bell character.</li>
|
||
<li>Fixed <a href="https://github.com/chrisant996/clink/issues/48">#48</a>; <code>menu-complete</code> gets stuck.</li>
|
||
<li>Fixed <a href="https://github.com/chrisant996/clink/issues/47">#47</a>; <kbd>Alt</kbd>+<kbd>D</kbd> erases history instead of word.</li>
|
||
<li>Fixed <a href="https://github.com/chrisant996/clink/issues/46">#46</a>; typing <code>..</code> in subdirectory of root doesn't work.</li>
|
||
<li>Fixed restoring color after pager when showing help.</li>
|
||
<li>Fixed <code>clink set</code> match completions for color settings.</li>
|
||
</ul>
|
||
<h3 id="v1117">v1.1.17</h3>
|
||
<ul>
|
||
<li>Added <code>os.getbatterystatus()</code> function that gets battery status information much faster than launching <code>wmic</code>.</li>
|
||
<li>Fixed <a href="https://github.com/chrisant996/clink/issues/44">#44</a>; Path completion doesn't work with <code>cd /d</code>.</li>
|
||
<li>Fixed loading scripts to ignore loading clink.lua, so that loading scripts behaves like Clink v0.4.9.</li>
|
||
</ul>
|
||
<h3 id="v1116">v1.1.16</h3>
|
||
<ul>
|
||
<li>Added <code>match.ignore_accent</code> setting (enabled by default) that ignores Latin alphabet diacriticals when completing matches (e.g. <code>ä</code> matches <code>a</code>, <code>ı</code> matches <code>i</code>, <code>ł</code> matches <code>l</code>, etc).</li>
|
||
<li>Fixed <a href="https://github.com/chrisant996/clink/issues/42">#42</a>; history lines are split on special characters.</li>
|
||
<li>Fixed <a href="https://github.com/chrisant996/clink/issues/41">#41</a>; Enable custom doskey handling of <code>..</code> and <code>-</code>.</li>
|
||
<li>Fixed Readline bug inserting dir matches; <code>\win_ foo</code> (cursor at <code>_</code>) would become <code>\Windows\\_ foo</code>.</li>
|
||
<li>Fixed the <code>quoted-insert</code> command to insert just <code>\x1b</code> when <kbd>ESC</kbd> is pressed.</li>
|
||
</ul>
|
||
<h3 id="v1115">v1.1.15</h3>
|
||
<ul>
|
||
<li>Migrating settings now immediately writes a new settings file, instead of waiting until a setting is changed.</li>
|
||
<li>Added support to detect when running in Windows Terminal and use native terminal support (which enables things like Xterm 256 and 24-bit color support).</li>
|
||
<li>Added terminal emulation support for Xterm 256 and 24-bit color escape codes. Clink maps the specified color to the most similar color in the active 16 color palette (using the CIELAB color space). To get full support for 24-bit color, it's necessary to use ConEmu or Windows Terminal or a similar console host, or to set <code>terminal.emulation</code> to <code>native</code> (which isn't supported on some older Windows OS versions).</li>
|
||
<li>Allow doskey macros named <code>..</code> or <code>-</code>, and also now doskey macros that resolve to <code>..</code> or <code>-</code> or a directory name will work (just like if the macro text had been typed at the Clink prompt).</li>
|
||
<li>Fixed compatibility problem with various scripts getting the %HOME% environment variable. Now if it isn't set, then Clink synthesizes %HOME% from %HOMEDRIVE% and %HOMEPATH% or from %USERPROFILE%.</li>
|
||
<li>Fixed saving color settings to behave like other settings: only write a setting's value to the setting file if it differs from the default value.</li>
|
||
<li>Fixed the <code>clink.print()</code> Lua function so it also works during loading scripts and during prompt filtering.</li>
|
||
<li>Fixed the Readline input text display getting garbled if the filtered prompt includes Xterm's OSC window title code (<code>\x1b]0;text\x07</code>). Clink doesn't support that escape code, but at no longer garbles the input text if that escape code is present.</li>
|
||
</ul>
|
||
<h3 id="v1114">v1.1.14</h3>
|
||
<ul>
|
||
<li>Migrate settings and history from an old version of Clink, if present. This only happens if the new-version Clink settings or history files don't exist. (Deleting an existing new-version Clink settings or history file will cause migration to happen again.)</li>
|
||
<li>Added <code>color.prompt</code> setting for backward compatibility with Clink v0.4.x.</li>
|
||
</ul>
|
||
<h3 id="v1113">v1.1.13</h3>
|
||
<ul>
|
||
<li>Fixed <code>clink.arg.register_parser</code> backward compatibility.</li>
|
||
</ul>
|
||
<h3 id="v1112">v1.1.12</h3>
|
||
<ul>
|
||
<li>Added <code>clink.ondisplaymatches()</code> as a replacement for the deprecated <code>clink.match_display_filter</code>. The new API is able to support popup list windows as well.</li>
|
||
<li>Speculative possible fix for <a href="https://github.com/chrisant996/clink/issues/35">#35</a> Crash when clink on clink.bat.</li>
|
||
<li>Fixed <a href="https://github.com/chrisant996/clink/issues/33">#33</a>; Tab autocomplete, auto-quoting paths doesn't seem to work as in Clink 0.4.9.</li>
|
||
</ul>
|
||
<h3 id="v1111">v1.1.11</h3>
|
||
<ul>
|
||
<li>Changed to load Lua scripts only once per session, unless forced to reload them. This enables backward compatibility for things like <a href="https://github.com/skywind3000/z.lua">z.lua</a> which has certain features that rely on Clink only loading scripts once per session.</li>
|
||
<li>Added <code>clink.onbeginedit()</code> so scripts can register a callback function to run each time the edit prompt is activated.</li>
|
||
<li>Added <code>lua.reload_scripts</code> setting to optionally force reloading Lua scripts each time the edit prompt is activated.</li>
|
||
<li>Added <code>color.message</code> setting for the Readline message area color (e.g. the search prompt message or digit argument prompt message, etc).</li>
|
||
<li>Fixed stray sticky <code>=</code> appended to completions after typing <code>set </code> and then typing a different command.</li>
|
||
</ul>
|
||
<h3 id="v1110">v1.1.10</h3>
|
||
<ul>
|
||
<li>Fixed <a href="https://github.com/chrisant996/clink/issues/32">#32</a>; hooking <code>ReadConsoleW</code> on Windows 7.</li>
|
||
</ul>
|
||
<h3 id="v119">v1.1.9</h3>
|
||
<ul>
|
||
<li>Added backward compatibility for <code>clink.match_display_filter</code>. The clink-completions/git.lua script uses it a lot, and that should all be working now.</li>
|
||
<li><code>settings.add</code> adds a color setting when the type is string and the name starts with "color.".</li>
|
||
<li><code>settings.get</code> now has an extra parameter to request the user friendly color name when getting a color setting.</li>
|
||
<li>Added <code>clink.version_encoded</code> variable with the Clink version number as <em>MMmmmpppp</em> (e.g. v1.1.9 is <code>10010009</code>) to make it easy for scripts to check for feature availability.</li>
|
||
<li>The <code>clink info</code> command now shows Lua script paths as well.</li>
|
||
<li>Fixed backward compatibility for loading scripts from the profile directory (if <code>clink.path</code> isn't set, then load scripts from the DLL directory and the profile directory).</li>
|
||
<li>Fixed some <code>color.input</code> bleed through to other things (introduced in v1.1.5).</li>
|
||
<li>Fixed scroll commands (regression introduced by input line color in v1.1.5).</li>
|
||
<li>Fixed horizontally sorted match display and re-enabled the performance fix from v1.1.4.</li>
|
||
<li>Fixed wildcard evaluation with non-file and non-directory matches (e.g. a branch name <code>origin/master</code> accidentally didn't match <code>or</code> or <code>*ma</code> because of the <code>/</code>).</li>
|
||
<li>Fixed sort order of <code>foo\</code> vs <code>foo.bar\</code> when displaying matches or using the <code>menu-complete</code> family of commands.</li>
|
||
<li>Fixed potentially-missing trailing path separator when <code>menu-complete</code> completes a directory match (regression introduced by wildcard matching in v1.1.5).</li>
|
||
<li>Other obscure minor fixes.</li>
|
||
</ul>
|
||
<h3 id="v118">v1.1.8</h3>
|
||
<ul>
|
||
<li>Fixed file match completions when an argmatcher only generates flag matches.</li>
|
||
<li>Fixed automatic inferring whether Readline should use filename completion and/or display rules (regression introduced by backward compatibility in v1.1.3-alpha).</li>
|
||
<li>Fixed backward compatibility for <code>clink.find_files()</code> and <code>clink.find_dirs()</code> (regression introduced by performance improvement in v1.1.7).<ul>
|
||
<li>Ignore extra arguments after the first one (the performance improvement in v1.1.7 revealed that some scripts call <code>clink.find_files()</code> with extra invalid arguments; e.g. clink-completions/modules/matchers.lua).</li>
|
||
<li>Don't append a trailing path separator on directory names returned by these functions (the new <code>os.globfiles()</code> and <code>os.globdirs()</code> functions do, but the old <code>clink.find_files()</code> and <code>clink.find_dirs()</code> functions should not).</li>
|
||
</ul>
|
||
</li>
|
||
<li>Fixed backward compatibility for coloring matches (regression introduced by backward compatibility changes in v1.1.4).</li>
|
||
</ul>
|
||
<h3 id="v117">v1.1.7</h3>
|
||
<ul>
|
||
<li>Performance improvement when displaying matches: When enumerating files and dirs, the <code>os.globfiles</code> and <code>os.globdirs</code> functions have all the info about each file. Now they can return that info in a table. This frees the match display function from needing to do any further file system IO. The performance boost is noticeable.</li>
|
||
<li>Rewrote the color settings: the .fg and .bg sub-settings are gone, and the main setting now uses a more natural syntax (e.g. <code>clink set color.input bright yellow</code> or <code>clink set color.modmark bright cyan on blue</code>).</li>
|
||
<li>Added "cmd" match type for shell (CMD.EXE) command completions.</li>
|
||
<li>Added VT emulation for the reverse video SGR parameters.</li>
|
||
<li>Fixed tab completion for <code>clink set <em>setting</em></code>, and also handle the new color setting syntax.</li>
|
||
<li>Fixed confusing behavior if multiple scripts try to add settings with the same name (now the first one succeeds and the rest report errors).</li>
|
||
</ul>
|
||
<h3 id="v116">v1.1.6</h3>
|
||
<ul>
|
||
<li>Hooked up tilde completion in the <code>cd</code>, <code>md</code>, and <code>rd</code> command argmatchers.</li>
|
||
<li>Hooked up tilde completion with the <code>exec.enable</code> setting ("~\pro" matches "C:\Users\myusername\program.exe").</li>
|
||
<li>When <code>terminal.emulation</code> is <code>auto</code>, now it also detects ANSI{32|64}.DLL just like Clink 0.4.8 did.</li>
|
||
</ul>
|
||
<h3 id="v115">v1.1.5</h3>
|
||
<ul>
|
||
<li>The <code>menu-complete</code> family of commands now support matching <code>?</code> and <code>*</code> wildcards when the <code>match.wild</code> setting is enabled.</li>
|
||
<li>Added <code>colour.input</code> and <code>colour.modmark</code> settings for coloring Readline's input line.</li>
|
||
<li>Added <code>clink.upper()</code> Lua function, and both <code>clink.lower()</code> and <code>clink.upper()</code> are properly UTF8 aware now.</li>
|
||
<li>Added <code>clink-copy-word</code> command that copies the word at the cursor to the clipboard.</li>
|
||
<li>Added <code>clink.promptfilter</code> setting to control whether to filter the prompt with Lua scripts.</li>
|
||
<li>Renamed <code>terminal.emulate</code> setting to <code>terminal.emulation</code>.</li>
|
||
<li>Improved executable file extension logic to consistently use %PATHEXT% (and efficiently).</li>
|
||
<li>Improved file extension logic (e.g. "file.foo bar" has no extension because of the space).</li>
|
||
<li>Updated arg matcher for <code>clink</code> itself (was missing some flags).</li>
|
||
<li>Changed <code>colour.hidden</code> setting to not be set by default.</li>
|
||
<li>Fixed <a href="https://github.com/chrisant996/clink/issues/28">#28</a>; Tab completion for "~" does not work.</li>
|
||
<li>Fixed <a href="https://github.com/chrisant996/clink/issues/25">#25</a>; Unicode surrogate pairs (and emoji) input isn't working -- Microsoft Terminal renders the text correctly, but ConEmu and the default conhost still don't (and that isn't a Clink issue).</li>
|
||
<li>Fixed screen size bug in Readline on Windows.</li>
|
||
<li>Fixed the backwards values in the <code>terminal.emulation</code> setting.</li>
|
||
<li>Fixed <code>....</code> so it works properly again.</li>
|
||
<li>Fixed case sensitive sorting of matches.</li>
|
||
<li>Fixed script error when %PATHEXT% is empty.</li>
|
||
<li>Fixed the <code>exec.cwd</code> Clink setting to default to true, so that the default behavior is consistent with how v0.4.x behaved.</li>
|
||
<li>Fixed the <code>cd</code>, <code>md</code>, <code>rd</code>, etc argmatchers to only match one argument to be consistent with the actual command syntax.</li>
|
||
</ul>
|
||
<h3 id="v114">v1.1.4</h3>
|
||
<ul>
|
||
<li>Automatically detect when running inside ConEmu and disable Clink's Virtual Terminal emulation.</li>
|
||
<li>Added <code>search-ignore-case</code> inputrc variable that makes the history search commands case insensitive.</li>
|
||
<li>Suppress adding a space after completing a flag match that ends with <code>:</code> or <code>=</code> (e.g. <code>msbuild -maxCpuCount:</code>).</li>
|
||
<li>Report any errors while loading Lua scripts.</li>
|
||
<li>Report an error if a Lua script tries to add a flag string that begins with a letter.</li>
|
||
<li>Fixed slow printing of possible matches. Readline is inefficient about emitting output, so Clink supplies a custom implementation.</li>
|
||
<li>Fixed some bugs in auto detection of flag prefix characters.</li>
|
||
<li>Fixed backward compatibility for flags, and for args when merging two parsers by calling <code>clink.arg.register_parser('foo')</code> multiple times for the same command string.</li>
|
||
<li>Fixed truncated message when the last line of a prompt exceeds 128 characters.</li>
|
||
<li>Fixed abort (<kbd>Ctrl</kbd>+<kbd>G</kbd> or <kbd>Esc</kbd>) in non-incremental history search mode.</li>
|
||
<li>Fixed saved values for settings added by Lua scripts; now the saved value is available to the script immediately on adding the setting, and saved values are retained even if the setting isn't always added by the script.</li>
|
||
<li>Fixed (and documented) shorthand form for defining an argmatcher.</li>
|
||
<li>Fixed length of colored match prefix after a path separator.</li>
|
||
<li>Fixed normalizing a slash by itself (<code>command /</code> mustn't become <code>command \</code> since that can interfere with completing flags).</li>
|
||
<li>Fixed the <code>completion-auto-query-items</code> inputrc variable.</li>
|
||
<li>Fixed the key binding list to correctly respect <code>completion-display-width</code>.</li>
|
||
<li><em>No visible effect yet: internal change that parses the input line to identify colors to use for each word (command, argument, flag, etc), but the colors aren't yet applied to the input line.</em></li>
|
||
</ul>
|
||
<h3 id="v113-alpha">v1.1.3-alpha</h3>
|
||
<ul>
|
||
<li>Fixed argmatcher lookup to be more strict, like in Clink 0.4.9 (match exact names, or name plus an extension from %PATHEXT%).</li>
|
||
<li>Backward compatibility:<ul>
|
||
<li>Most things should work now.</li>
|
||
<li>Dropping the new Clink on top of the vendor\clink directory in Cmder seems to work -- <em>but make a backup before you try this at home!</em></li>
|
||
</ul>
|
||
</li>
|
||
<li>API changes:<ul>
|
||
<li>Added <code>log.info()</code> function.</li>
|
||
<li>Added Clink version numbers in <code>clink.version_major</code>, etc.</li>
|
||
<li>Added <code>_argmatcher:getwordbreakinfo()</code> callback; removed <code>_argmatcher:setprefixincluded()</code> (it was a mess, and it was new to v1.x, so there's no compatibility concern with removing it).</li>
|
||
<li>Deprecated <code>_argmatcher:setflagprefix()</code>; now it happens automagically when using <code>_argmatcher:addflags()</code>.</li>
|
||
<li>Introduced several deprecated functions to support backward compatibility.</li>
|
||
</ul>
|
||
</li>
|
||
<li>Improvements to Lua debugger:<ul>
|
||
<li>Added <code>lua.traceback_on_error</code>, <code>lua.break_on_error</code>, and <code>lua.break_on_traceback</code> settings to make debugging script errors easier.</li>
|
||
<li>Made <code>pause()</code> consistent about pausing in the caller (rather than sometimes inside the pause command itself).</li>
|
||
<li>The debugger automatically shows the stack trace when entering debug mode, and on every pause.</li>
|
||
<li>Show 3 lines of source context by default.</li>
|
||
<li>The help list is sorted now.</li>
|
||
<li>Fixed the <code>set</code> command in the debugger to behave as documented.</li>
|
||
</ul>
|
||
</li>
|
||
</ul>
|
||
<h3 id="v112-alpha">v1.1.2-alpha</h3>
|
||
<ul>
|
||
<li>Documentation is mostly updated; just the argmatcher Lua API and Clink command line options are left to be documented.</li>
|
||
<li>Added <code>history.max_lines</code> setting that controls how many lines of command history to save (1 to 50000, default is 2500).</li>
|
||
<li>Added <code>readline.hide_stderr</code> setting that can suppress stderr output from the Readline library.</li>
|
||
<li>For backward compatibility with 0.4.8, <code>clink_inputrc</code> files are loaded as well.</li>
|
||
<li>Lua script API changes:<ul>
|
||
<li><code>addmatch()</code> in Lua scripts takes an optional match type argument.</li>
|
||
<li>Removed <code>displayable</code>, <code>aux</code>, and <code>suffix</code> fields in matches.</li>
|
||
<li>Revert the change to disallow mixing file/directory/symlink with other match types (it broke the tests and certain completion scenarios).</li>
|
||
</ul>
|
||
</li>
|
||
<li>Fixed issues:<ul>
|
||
<li><a href="https://github.com/chrisant996/clink/issues/18">#18</a> alt+digit then alt+ctrl+y isn't working.</li>
|
||
<li><a href="https://github.com/chrisant996/clink/issues/17">#17</a> arrow keys don't exit <code>reverse-search-history</code> like in bash.</li>
|
||
<li><a href="https://github.com/chrisant996/clink/issues/16">#16</a> problems with $T in doskey macros.</li>
|
||
<li><a href="https://github.com/chrisant996/clink/issues/13">#13</a> <code>clink history delete <n></code> returns a CRT error.</li>
|
||
</ul>
|
||
</li>
|
||
<li>Other fixes:<ul>
|
||
<li>There should be no more problems running on Windows Insider builds because Clink now uses <a href="https://github.com/microsoft/detours">Detours</a> for hooking APIs.</li>
|
||
<li>Fixed crash in <code>insert-completions</code> due to heap failure (introduced by the performance changes for displaying matches).</li>
|
||
<li>Fixed <code>clink</code> and <code>history</code> built-in aliases (solve glitchy path problem).</li>
|
||
<li>Fixed scrolling to top of screen buffer.</li>
|
||
<li>Fixed env var and <code>set</code> completions.</li>
|
||
<li>Fixed <code>tilde-expand</code> for quoted text.</li>
|
||
<li>Fixed <kbd>Esc</kbd> in Readline's digit argument input mode (it doesn't try to cancel the mode, because that's not how Readline is documented to work).</li>
|
||
<li>Fixed exit code from some <code>clink</code> command line options.</li>
|
||
</ul>
|
||
</li>
|
||
<li>Set locale to UTF8 much earlier to avoid quirky behavior early in script processing.</li>
|
||
</ul>
|
||
<h3 id="v111-alpha">v1.1.1-alpha</h3>
|
||
<ul>
|
||
<li>Exclusively use Readline's completion implementation. This (with fixes and enhancements in Readline itself) makes the completion experience much nicer and more sophisticated, and removes a lot of code that was added in v1.0.0a0.</li>
|
||
<li>Exclusively use Readline's key binding implementation. This makes it possible to have a single consistent way to set key bindings (inputrc) and for <code>clink-show-help</code> to list all key bindings, and removes a lot of code that was added in v1.0.0a0.</li>
|
||
<li>Converted all of Clink's internal key behaviors to be implemented as commands that can be bound in the inputrc file.</li>
|
||
<li>Rewrote and refactored the pagination routine to be used in multiple places.</li>
|
||
<li>Fixed prompt filtering to correctly use the specified priority order.</li>
|
||
<li>Readline library:<ul>
|
||
<li>Updated the Readline library from v6.2 to v8.0. This picked up lots of bug fixes and new capabilities (for example colored completions).</li>
|
||
<li>Changed Readline to support backslash as a path separator.</li>
|
||
<li>The pager prompt in Readline is optionally colored, controlled by the <code>colour.interact</code> Clink setting.</li>
|
||
<li>Added <code>completion-auto-query-items</code> config variable (on by default) which asks whether to list possible matches when the number of lines listed will fill one screen page.</li>
|
||
<li>Added <code>history-point-at-end-of-anchored-search</code> config variable in inputrc to make the cursor point behave like 4Dos/4NT/TakeCommand when searching forward and backward through command history.</li>
|
||
<li>Fixed prev history at top of history.</li>
|
||
<li>Fixed to get the current values of environment variables when needed, rather than always getting the value from whenever Clink was started.</li>
|
||
<li>Fixed coloring directory completions.</li>
|
||
<li>Fixed <code>menu-complete</code> for <code>\dir</code> and <code>.</code> and <code>..</code>.</li>
|
||
<li>Fixed slow performance when displaying matches. Readline was calling stat() at least once per match (!!). A new match type field enables faster performance, coloring readonly and hidden file matches, applying filename completion rules only to filenames (vs branch names or other text strings), correct match de-duplication, and more. The Lua match APIs can supply the new match type.</li>
|
||
<li>Fixed inserting a completion to happen as a single undo group.</li>
|
||
<li>Fixed tilde to map to <code>%USERPROFILE%</code> instead of <code>%APPDATA%</code> on Windows.</li>
|
||
</ul>
|
||
</li>
|
||
<li>Typing a directory by itself uses <code>cd /d</code> to change to the directory:<ul>
|
||
<li>Typing a directory with a trailing path separator changes to the directory.</li>
|
||
<li>Typing <code>..\</code> changes to the parent directory.</li>
|
||
<li>Typing <code>...</code> or <code>....</code> etc moves up an extra parent directory level for each extra dot (2 dots move up one parent, 3 dots moves up two parents, etc). A trailing path separator is optional when there are more than 2 dots.</li>
|
||
<li>Typing <code>-</code> or <code>cd -</code> or <code>chdir -</code> changes to the previous directory.</li>
|
||
</ul>
|
||
</li>
|
||
<li>Commands that are new, enhanced, or fixed:<ul>
|
||
<li>Added <code>add-history</code> and <code>remove-history</code> commands (similar to 4Dos/4NT/TakeCommand).</li>
|
||
<li>Got the <code>menu-complete</code>, <code>menu-complete-backward</code>, and <code>old-menu-complete</code> commands working (they never worked properly before in Clink).<ul>
|
||
<li>Also added a corresponding <code>old-menu-complete-backward</code> command for reverse order.</li>
|
||
<li>All of the <code>*-menu-complete-*</code> commands support wildcards (<code>*</code> and <code>?</code>).</li>
|
||
</ul>
|
||
</li>
|
||
<li>Added <code>clink-show-help</code> command (<kbd>Alt</kbd>+<kbd>H</kbd>). The help now lists <em><strong>all</strong></em> key bindings, and it shows user-friendly key names (like <code>A-Up</code> or <code>C-x,C-r</code> or <code>C-S-PgUp</code> or <code>A-C-S-F3</code>).</li>
|
||
<li>Added <code>clink-popup-completions</code> command that shows a popup window listing possible completions. <kbd>Enter</kbd> inserts the highlighted completion.</li>
|
||
<li>Added <code>clink-popup-directories</code> command that shows a popup window listing recent directories. <kbd>Enter</kbd> changes to the highlighted directory, or <kbd>Shift</kbd>+<kbd>Enter</kbd> inserts the highlighted directory in the editing line (or <kbd>Ctrl</kbd>+<kbd>Enter</kbd>).</li>
|
||
<li>Added <code>clink-popup-history</code> command that shows a popup window listing command history. <kbd>Enter</kbd> executes the highlighted command, or <kbd>Shift</kbd>+<kbd>Enter</kbd> jumps to the highlighted command in the history (or <kbd>Ctrl</kbd>+<kbd>Enter</kbd>).</li>
|
||
<li>Added <code>clink-scroll-lineup</code>, <code>clink-scroll-linedown</code>, <code>clink-scroll-page-up</code>, <code>clink-scroll-page-down</code>, <code>clink-scroll-top</code>, and <code>clink-scroll-bottom</code> commands that do what it looks like they'd do and are bound to the keys it looks like they'd be.</li>
|
||
<li>Added <code>clink-expand-doskey</code> command (<kbd>Ctrl</kbd>+<kbd>Alt</kbd>+<kbd>f</kbd>) that expands the current line according to the current doskey aliases.</li>
|
||
<li>Added <code>clink-expand-env-var</code> command (<kbd>Ctrl</kbd>+<kbd>Alt</kbd>+<kbd>e</kbd>) that expands the environment variable at the cursor point.</li>
|
||
<li>Added <code>clink-exit</code> command (<kbd>Alt</kbd>+<kbd>F4</kbd>) that exits CMD.</li>
|
||
</ul>
|
||
</li>
|
||
<li>Fixed keyboard input issues:<ul>
|
||
<li><kbd>Esc</kbd> is a bindable key now (<code>\e[27;27~</code>).</li>
|
||
<li>Added more bindable key combinations (run <code>clink echo</code> then press keys to see the key sequence to use in the inputrc file).</li>
|
||
<li><kbd>Ctrl</kbd>+<kbd>@</kbd> (NUL) didn't work.</li>
|
||
<li><kbd>Ins</kbd> toggles insert/overwrite mode.</li>
|
||
<li>Unbound keys are ignored now, instead of inserting gibberish characters (part of the terminal internal key sequence).</li>
|
||
<li>Fixed input handling so the <code>quoted-insert</code> command can work properly.</li>
|
||
<li>Fixed <kbd>Esc</kbd> while searching.</li>
|
||
<li>Fixed vi mode (was working in v0.4.9, but not in v1.0.x).</li>
|
||
</ul>
|
||
</li>
|
||
<li>Fixed command history issues:<ul>
|
||
<li>The <code>dont_add_to_history_cmds</code> Clink setting is a space-delimited list of commands to not add to history.</li>
|
||
<li>Fixed bleeding between history banks.</li>
|
||
<li>Fixed uninitialized variable that made history updates intermittently do nothing or corrupt the other history bank.</li>
|
||
<li>Fixed output from <code>clink history</code> to convert to UTF16 when writing to the console (but write UTF8 when output is redirected).</li>
|
||
</ul>
|
||
</li>
|
||
<li>Fixed terminal output issues:<ul>
|
||
<li>Added <code>terminal.emulate</code> Clink setting that controls whether Clink does VT emulation or passes all ANSI escape codes directly to the console host. For example, this lets the prompt and completion coloring take advantage of more sophisticated ANSI escape codes such as XTerm 256 color and 16 bit color support.</li>
|
||
<li>Added back support for the <code>prefer-visible-bell</code> config variable.</li>
|
||
<li>Fixed underline support.</li>
|
||
<li>Fixed handling for UTF8 output from Readline.</li>
|
||
<li>Fixed invisible cursor point in Lua debugger.</li>
|
||
</ul>
|
||
</li>
|
||
<li>Completions:<ul>
|
||
<li>Added <code>match.sort_dirs</code> Clink setting that specifies where to sort directories in the list of possible completions: before files, mixed in with files, or after files.</li>
|
||
<li>Don't attempt completing incomplete UNC paths: at least the <code>\\server\share\</code> path components are required (for anything shorter the OS APIs are guaranteed to fail, but will fail slowly).</li>
|
||
<li>Fixed sorting to use Unicode aware locale based sorting (like Windows does) instead of dumb UTF8 byte comparisons.</li>
|
||
<li>Fixed arbitrary limit on completions (had been limited to 64KB worth of completions).</li>
|
||
<li>Fixed quoting spaces in completions.</li>
|
||
<li>Fixed to use the same list as CMD for characters that require quoting.</li>
|
||
<li>Fixed normalizing UNC paths.</li>
|
||
<li>Fixed volume relative completions (e.g. <code>x:foo</code>).</li>
|
||
<li>Disallow mixing file/directory/symlink with other match types. This was to avoid a confusing/malfunctioning case in match display and prefix highlighting.</li>
|
||
</ul>
|
||
</li>
|
||
<li>Fixed UTF8 encoding in various Lua functions.</li>
|
||
<li>Fixed printing stderr output from Readline, Lua, and Clink.</li>
|
||
<li>Fixed crashes and other failures when starting Clink in 32 bit CMD.</li>
|
||
<li>Fixed some memory leaks that accumulated with each new line of input.</li>
|
||
<li>Fixed prompt filtering API to be backward compatible with v0.4.9 scripts.</li>
|
||
<li>Fixed Lua errors from <code>clink set</code> (it neglected to fully initialize Clink's Lua integration before loading Lua scripts).</li>
|
||
<li>Fixed UTF8 conversion bug that could truncate a string without fully converting it.</li>
|
||
<li>Fixed serious rampant memory corruption bug in v1.0.x (not present in v0.4.9), which had been causing intermittent malfunctions and data corruption and crashes.</li>
|
||
<li>Fixed multi-line doskey macros to show the prompt in between lines, like CMD does.</li>
|
||
<li>Removed the 4096 byte limit on input.</li>
|
||
<li>Renamed the Clink DLL back to what it was in v0.4.x, to fix compile time problems.</li>
|
||
<li>Other fixed issues:<ul>
|
||
<li><a href="https://github.com/mridgers/clink/issues/544">mridgers #544</a> Clink v1.0.0.a1 doesn't support cyrillic characters keyboard input on Windows 10 with console V2.</li>
|
||
<li><a href="https://github.com/mridgers/clink/issues/543">mridgers #543</a> Not compatible with Windows Insider Build 20150.</li>
|
||
<li><a href="https://github.com/mridgers/clink/issues/537">mridgers #537</a> Clink breaks the CMDS tool.</li>
|
||
<li><a href="https://github.com/mridgers/clink/issues/520">mridgers #520</a> Clink 1.0.0.a1 - <code>clink set history_io 1</code> Error.</li>
|
||
<li><a href="https://github.com/mridgers/clink/issues/519">mridgers #519</a> Clink v1.0.0.a1 - <code>-s|--scripts [path]</code> command line arg removed?</li>
|
||
<li><a href="https://github.com/mridgers/clink/issues/516">mridgers #516</a> Doskey $T not handled properly.</li>
|
||
<li><a href="https://github.com/mridgers/clink/issues/512">mridgers #512</a> Command history missing in .history.</li>
|
||
<li><a href="https://github.com/mridgers/clink/issues/503">mridgers #503</a> Keyboard shortcut for scrolling.</li>
|
||
<li><a href="https://github.com/mridgers/clink/issues/501">mridgers #501</a> <kbd>Ctrl</kbd>+<kbd>Backspace</kbd> works now.</li>
|
||
<li><a href="https://github.com/mridgers/clink/issues/487">mridgers #487</a> Clink breaks ConEmu-specific Escape codes.</li>
|
||
<li><a href="https://github.com/mridgers/clink/issues/480">mridgers #480</a> History never saved.</li>
|
||
<li><a href="https://github.com/mridgers/clink/issues/465">mridgers #465</a> Using LuaJIT (FFI).</li>
|
||
<li><a href="https://github.com/mridgers/clink/issues/456">mridgers #456</a> Clear-screen not working properly when PROMPT is two lines long.</li>
|
||
<li><a href="https://github.com/mridgers/clink/issues/453">mridgers #453</a> Wrong cursor position when a line contains non-printable characters.</li>
|
||
<li><a href="https://github.com/mridgers/clink/issues/442">mridgers #442</a> Unable to paste more than 1024 characters using <kbd>Ctrl</kbd>+<kbd>V</kbd>.</li>
|
||
<li><a href="https://github.com/mridgers/clink/issues/422">mridgers #422</a> Problem with filename modifiers.</li>
|
||
<li><a href="https://github.com/mridgers/clink/issues/420">mridgers #420</a> Use NtSuspendProcess instead of CreateToolhelp32Snapshot to freeze the threads.</li>
|
||
<li><a href="https://github.com/mridgers/clink/issues/372">mridgers #372</a> Provide a way to select a previous directory.</li>
|
||
<li><a href="https://github.com/mridgers/clink/issues/365">mridgers #365</a> history-search behavior.</li>
|
||
<li><a href="https://github.com/mridgers/clink/issues/342">mridgers #342</a> Clink_inputrc not being processed if it the clink_inputrc is a link (created via mklink).</li>
|
||
</ul>
|
||
</li>
|
||
<li>Fixed many other bugs.</li>
|
||
</ul>
|
||
<h2 id="releases-from-mridgersclink-original-repo">Releases from <a href="https://github.com/mridgers/clink">mridgers/clink</a> original repo</h2>
|
||
<h3 id="v100a1-alpha-test-release">v1.0.0a1 <em>(alpha test release)</em></h3>
|
||
<ul>
|
||
<li>Improve terminal integration with the Readline library.</li>
|
||
<li>Internal improvements to the built-in ecma48 terminal emulator.</li>
|
||
<li>Fixed use after free in Doskey emulation.</li>
|
||
<li>Fixed dash-dash flag completion.</li>
|
||
<li>Search ancestors for a compatible target process (for when cmd.exe starts another process that subsequently starts clink; especially useful during development).</li>
|
||
<li>Use clink/terminal's wcwidth() implementation.</li>
|
||
<li>screen_buffer::set_cursor() should be relative to the visible area.</li>
|
||
<li>Try to adjust the cursor position better when resizing the terminal.</li>
|
||
<li>Some internal Lua functions needed the unquoted clink exe path.</li>
|
||
<li>The origin path now affects the hash in the dll cache, to guard against directory moves.</li>
|
||
<li>More code reorganization.</li>
|
||
</ul>
|
||
<h3 id="v100a0-alpha-test-release">v1.0.0a0 <em>(alpha test release)</em></h3>
|
||
<ul>
|
||
<li>Extensive code reorganization, refactoring, and rewriting -- multiple times -- almost everything was touched.</li>
|
||
<li>OS integration:<ul>
|
||
<li>Fixed Doskey macros on Win8, and on Win10.</li>
|
||
<li>Fixed <code>clink_x??.exe</code> startup stall on Windows 10.</li>
|
||
<li>Removed XP support. It doesn't load DLLs like Clink uses them.</li>
|
||
<li>Removed Powershell support.</li>
|
||
</ul>
|
||
</li>
|
||
<li>Readline integration:<ul>
|
||
<li>Search for multiple places for [.|_]inputrc (fixes <a href="https://github.com/mridgers/clink/issues/258">mridgers #258</a>).</li>
|
||
<li>Disabled Readline's completion code, and only use the clink alternative code.</li>
|
||
<li>Removed redundant slash translation and shims to make it happen.</li>
|
||
<li>Removed control of Readline's suffix appending and disabled it.</li>
|
||
</ul>
|
||
</li>
|
||
<li><code>clink</code> commands and flags:<ul>
|
||
<li>Changed <code>--cfgdir</code> to <code>--profile</code>, it's no longer required, and added help about it.</li>
|
||
<li>Added a <code>--version</code> option to print Clink's version.</li>
|
||
<li>Added <code>clink info</code> to print information about Clink.</li>
|
||
<li>Added <code>clink echo</code> command to echo input key sequences to stdout.</li>
|
||
<li>Added <code>clink history</code> command (fixes <a href="https://github.com/mridgers/clink/issues/172">mridgers #172</a>).</li>
|
||
<li>Added <code>history</code> as an alias for <code>clink history</code>.</li>
|
||
<li>Added internal <code>--list</code> flag to <code>clink set</code> for match generation.</li>
|
||
<li>Removed <code>--scripts</code> argument (fixes <a href="https://github.com/mridgers/clink/issues/206">mridgers #206</a>).</li>
|
||
<li>Updated <code>clink autorun</code> command's help text.</li>
|
||
</ul>
|
||
</li>
|
||
<li>Lua scripts:<ul>
|
||
<li>Prefer <code>userprofile</code> over other standard environment variables for where to look for lua scripts.</li>
|
||
<li>New API for argument style completion scripts.</li>
|
||
<li>Refactored prompt filtering, and introduced new prompt filtering API.</li>
|
||
<li>Refactored generating matches, and introduced new match generator API.</li>
|
||
<li>Removed built in completions scripts for git, go, hg, and p4. There's better ones.</li>
|
||
<li>Renamed many of clink's Lua functions.</li>
|
||
<li>Moved functions from <code>clink</code> to <code>os</code> in Lua.</li>
|
||
<li>Removed <code>clink.is_match()</code> in Lua; don't presume anything on anyone's behalf about matches.</li>
|
||
<li>Added some current dir functions in Lua.</li>
|
||
<li>Added some env/dir functions in Lua.</li>
|
||
<li>Exposed path manipulation functions to Lua.</li>
|
||
<li>Embed the core Lua scripts instead of loading them from files.</li>
|
||
</ul>
|
||
</li>
|
||
<li>Terminal IO:<ul>
|
||
<li>Added a module for scrolling the screen.</li>
|
||
<li>Rewrote the terminal emulation module, and all Readline IO goes through it.</li>
|
||
<li>Use VT220-style control codes for special keys.</li>
|
||
<li>If <kbd>Alt</kbd> is pressed send ESC in the input stream rather than setting meta bit.</li>
|
||
<li>Replaced wcwidth() with a more complete and correct version.</li>
|
||
</ul>
|
||
</li>
|
||
<li>Settings:<ul>
|
||
<li>Added <code>clink_path</code> setting for where to look for lua scripts.</li>
|
||
<li>Added <code>match.ignore_case</code> setting.</li>
|
||
<li>Added <code>files.unc_paths</code> setting for optional matching from UNC paths.</li>
|
||
<li>Added a setting to skip adding lines that start with <code>history</code>.</li>
|
||
<li>Removed <code>esc_clears_line</code> setting.</li>
|
||
<li>Pasting CRLFs doesn't really make sense.</li>
|
||
<li>Don't write out settings that are set to default.</li>
|
||
</ul>
|
||
</li>
|
||
<li>Make sure <kbd>Ctrl</kbd>-<kbd>C</kbd> doesn't modify history.</li>
|
||
<li>Make a cached copy of Clink's DLL when injecting so as to not lock the master.</li>
|
||
<li>Guard against Readline's writes to stderr.</li>
|
||
<li>Remove <code>clink_inputrc_base</code> file and embed its content (fixes <a href="https://github.com/mridgers/clink/issues/257">mridgers #257</a>).</li>
|
||
<li>Include more metadata in the Clink's executables.</li>
|
||
</ul>
|
||
<h3 id="v049">v0.4.9</h3>
|
||
<ul>
|
||
<li>Fixed broken Doskey on Win10 (#438, #451)</li>
|
||
</ul>
|
||
<h3 id="v048">v0.4.8</h3>
|
||
<ul>
|
||
<li>Environment variable <code>clink_profile</code> overrides Clink's profile path (#390).</li>
|
||
<li>Load a clink_inputrc file from Clink's profile directory (fixes #406).</li>
|
||
<li>Bug fixes;<ul>
|
||
<li>Redraw issues when prompts end in OSC ANSI codes (#387, #384).</li>
|
||
<li>Fixed <code>clink autorun --help</code> crash.</li>
|
||
</ul>
|
||
</li>
|
||
</ul>
|
||
<h3 id="v047">v0.4.7</h3>
|
||
<ul>
|
||
<li>Bug fixes;<ul>
|
||
<li>Sometimes autorun tries to run clink.exe (#374).</li>
|
||
<li>Autorun would cause cmd.exe to return an error if it wasn't interactive (#373).</li>
|
||
</ul>
|
||
</li>
|
||
</ul>
|
||
<h3 id="v046">v0.4.6</h3>
|
||
<ul>
|
||
<li>HOME is only set if it is currently unset.</li>
|
||
<li>Readline can be initialised with .inputrc and _inputrc files too (#258).</li>
|
||
<li>Bug fixes;<ul>
|
||
<li>Executable completion;<ul>
|
||
<li>Paths from PATH were checked twice.</li>
|
||
<li>Incorrect results were returned for words ending in <code>.</code> or <code>-</code>.</li>
|
||
<li>Directories . and .. were incorrectly displayed.</li>
|
||
</ul>
|
||
</li>
|
||
<li>Fixed a crash if .bat script's stdout is redirected (#366).</li>
|
||
<li>Occasional crash when injecting Clink (#351).</li>
|
||
<li>Display errors;<ul>
|
||
<li>When editing near the window's right-hand edge (#347).</li>
|
||
<li>Double display of multi-line prompts when resizing the terminal (#352).</li>
|
||
<li>Very rare wrap artefacts when making the terminal window larger.</li>
|
||
</ul>
|
||
</li>
|
||
<li>Doskey emulation (#344).</li>
|
||
<li>Improved <code>clink autorun</code> help (#348).</li>
|
||
<li>Fixed launching Clink when clink.bat is renamed (#357).</li>
|
||
</ul>
|
||
</li>
|
||
</ul>
|
||
<h3 id="v045">v0.4.5</h3>
|
||
<ul>
|
||
<li>Improved <code>clink autorun</code>. It now defaults to the Current User registry hive.</li>
|
||
<li><code>clink set</code> gives more details for enumeration-type settings.</li>
|
||
<li>Tab completion for p4vc.</li>
|
||
<li>New settings <code>history_expand_mode</code> to control history expansion in quotes (#317).</li>
|
||
<li>Bug fixes;<ul>
|
||
<li>Use full width of the terminal (#337).</li>
|
||
<li>Fixed MinGW compile error (#335).</li>
|
||
<li>Autorun now defaults to the current user's hive (#332).</li>
|
||
<li>Creating clink.html no longer needs Pandoc, plus it looks a bit better (#331).</li>
|
||
<li>Added settings to control history expansion (#326).</li>
|
||
<li>Correct fallback when <code>use_altgr_substitute</code> is off (#325).</li>
|
||
<li>Load history prior to saving it on shutdown (#318).</li>
|
||
<li>Added Shift-Tab documentation and menu completion example (#190).</li>
|
||
<li>Added shim for backwards menu completion (#190).</li>
|
||
<li>Input handling now outputs <code>\e`Z</code> for <kbd>Shift</kbd>-<kbd>Tab</kbd> (#190).</li>
|
||
<li>Updated Readme with current Premake info (#310).</li>
|
||
<li>Guard against there being no buffer to read from (#304).</li>
|
||
<li>Fixed artefacts when resizing conhost's buffer (#139).</li>
|
||
<li>Clear remaining characters if scroll window was too small (#301)</li>
|
||
<li>Escape % characters when expanding aliases (#280).</li>
|
||
<li>Fixed leaking exception filters.</li>
|
||
<li>Clearing the screen doesn't leave artefacts behind.</li>
|
||
</ul>
|
||
</li>
|
||
</ul>
|
||
<h3 id="v044">v0.4.4</h3>
|
||
<ul>
|
||
<li>Completing .. behaves more like Bash (#277).</li>
|
||
<li>Escape from yes/no question when <kbd>Ctrl</kbd>+<kbd>C</kbd> is pressed.</li>
|
||
<li>Valid XP executables (#278, #289).</li>
|
||
<li>Fixed n-th argument yank not working as expected (#254).</li>
|
||
<li>Fixed prompt colours sometimes not working (#279, #286).</li>
|
||
<li>Fixed <code>!0</code> causing Clink to crash.</li>
|
||
<li>Save/restore cursor position in case Readline moves it.</li>
|
||
</ul>
|
||
<h3 id="v043">v0.4.3</h3>
|
||
<ul>
|
||
<li>Localised Y/N when auto-answering "terminate?" prompt.</li>
|
||
<li><code>$*</code> would early out if there was no arguments.</li>
|
||
<li>Disable ANSI code support if third party provides it.</li>
|
||
<li>Installer can now set %CLINK_DIR% to install location.</li>
|
||
<li>Improved output from <code>clink set</code>.</li>
|
||
<li>Support for Windows 10 Technical Preview.</li>
|
||
<li><kbd>Ctrl</kbd>-<kbd>L</kbd> now scrolls last line to the top of the window rather than clearing.</li>
|
||
<li>New option to control how newline characters are pasted to the line.</li>
|
||
<li>New options to control history;<ul>
|
||
<li><code>history_file_lines</code> - maximum lines saved to disk.</li>
|
||
<li><code>history_ignore_space</code> - ignore lines prefixed with whitespace.</li>
|
||
<li><code>history_dupe_mode</code> - how duplicate entries are handled.</li>
|
||
<li><code>history_io</code> - load/save history from disk every line.</li>
|
||
</ul>
|
||
</li>
|
||
<li>Fixed nonfunctional numpad keys.</li>
|
||
<li>Fixed missing WINCH signals if other processes resize the buffer.</li>
|
||
<li>Support <kbd>Alt</kbd> codes sent from Conhost.</li>
|
||
</ul>
|
||
<h3 id="v042">v0.4.2</h3>
|
||
<ul>
|
||
<li>Prompt colouring no longer requires third party ANSI code utility.</li>
|
||
<li>Override settings with environment variables prefixed with 'clink'.</li>
|
||
<li>Ctrl-PgUp goes up a directory.</li>
|
||
<li>Updated Go completions (by matrixik).</li>
|
||
<li>Arguments to clink.arg.new_parser() now initialise parser's flags/args (from vladimir-kotikov).</li>
|
||
<li>New clink.arg.add_flags() and clink.arg.add_arguments() functions.</li>
|
||
<li>Removed footer and <kbd>Alt</kbd>-<kbd>H</kbd> tip for more succinct stdout output.</li>
|
||
<li>Bug fixes;<ul>
|
||
<li>Windows XP works again.</li>
|
||
<li>Fixed race condition in lua_execute().</li>
|
||
</ul>
|
||
</li>
|
||
</ul>
|
||
<h3 id="v041">v0.4.1</h3>
|
||
<ul>
|
||
<li>Bug fixes;<ul>
|
||
<li>Various Unicode fixes causing corrupt environment variables.</li>
|
||
<li>Fixed thread resume/suspend causing rare system-wide deadlock.</li>
|
||
<li>Fixed incorrect translation of suffixed slash when completing flags.</li>
|
||
</ul>
|
||
</li>
|
||
<li>Add <code>--nolog</code> argument to disable file logging. Fix #187 Fix #154</li>
|
||
<li>Added missing escape sequences from doskey emulation.</li>
|
||
<li>Reinstated unix-kill-line key binding.</li>
|
||
<li>Mapped <kbd>PgUp</kbd>/<kbd>Down</kbd> to search history using line typed so far.</li>
|
||
<li>Added documentation covering escape codes for special keys.</li>
|
||
<li>Added support for Windows' <kbd>AltGr</kbd> substitute <kbd>Ctrl</kbd>-<kbd>Alt</kbd>.</li>
|
||
<li>Support for Readline's 'menu' style completion (see docs).</li>
|
||
</ul>
|
||
<h3 id="v04">v0.4</h3>
|
||
<ul>
|
||
<li>New features;<ul>
|
||
<li>Better <code>clink.arg</code> API. Easier, more intuitive, and more powerful.</li>
|
||
<li>Whitespace prefix skips exec matching.</li>
|
||
<li>Added a <code>set</code> verb to easily change settings from the command line.</li>
|
||
<li>Basic support for a shells other than cmd.exe.</li>
|
||
<li>Completion for Go (contributed by Dobroslaw Zybort).</li>
|
||
<li>Setting <code>exec_match_style</code> to -1 disables it entirely.</li>
|
||
<li>Make history persistence optional.</li>
|
||
<li>Alias/doskey completion.</li>
|
||
<li>Very basic support for Powershell.</li>
|
||
<li>View cmd.exe's autorun entry without needing admin rights.</li>
|
||
</ul>
|
||
</li>
|
||
<li>New key bindings;<ul>
|
||
<li><kbd>Ctrl</kbd>-<kbd>Alt</kbd>-<kbd>C</kbd> : Copy command line to the clipboard.</li>
|
||
<li><kbd>Ctrl</kbd>-<kbd>Alt</kbd>-<kbd>E</kbd> : Expand environment variable under cursor.</li>
|
||
<li><kbd>Ctrl</kbd>-<kbd>Alt</kbd>-<kbd>U</kbd> : "up directory" (formerly <kbd>Shift</kbd>-<kbd>Up</kbd>).</li>
|
||
<li><kbd>Ctrl</kbd>-<kbd>U</kbd> : Adds <code>..\</code> to the command line.</li>
|
||
<li><kbd>Alt</kbd>-<kbd>H</kbd> : Shows active keymap's key bindings.</li>
|
||
</ul>
|
||
</li>
|
||
<li>New Lua functions;<ul>
|
||
<li>clink.execute().</li>
|
||
<li>clink.get_host_process().</li>
|
||
<li>clink.match_files().</li>
|
||
<li>clink.match_words().</li>
|
||
<li>clink.get_console_aliases().</li>
|
||
</ul>
|
||
</li>
|
||
<li>Lots of bug fixes, including;<ul>
|
||
<li>Better command extraction.</li>
|
||
<li>Fixed cmd.exe command paging and <kbd>Ctrl</kbd>-<kbd>C</kbd>/<kbd>Ctrl</kbd>-<kbd>Break</kbd> handling.</li>
|
||
<li>Multiple locale fixes.</li>
|
||
<li>Use localised text for "Terminate batch job?" prompt.</li>
|
||
</ul>
|
||
</li>
|
||
</ul>
|
||
<h3 id="v03">v0.3</h3>
|
||
<ul>
|
||
<li>Automatic answering of cmd.exe's "Terminate batch script?" prompt.</li>
|
||
<li>Coloured prompts (requires ANSICON or ConEmu).</li>
|
||
<li>Added Shift-Up keyboard shortcut to automatically execute <code>cd ..</code></li>
|
||
<li>Mapped <kbd>Ctrl</kbd>-<kbd>Z</kbd> to undo, Microsoft style.</li>
|
||
<li>Improved integration of Readline;<ul>
|
||
<li>New input handling code (<kbd>Ctrl</kbd>-<kbd>Alt</kbd> combos now work).</li>
|
||
<li>An implementation of the Termcap library.</li>
|
||
<li>Fully functional Vi-mode support.</li>
|
||
<li>Support for resizable consoles.</li>
|
||
<li>Line wrapping now works correctly (issue 50).</li>
|
||
</ul>
|
||
</li>
|
||
<li>Adjustable executable match style (issue 65).</li>
|
||
<li>Improved environment variable completion.</li>
|
||
<li>Added settings file to customise Clink.</li>
|
||
<li>New Lua features and functions;<ul>
|
||
<li>Matches can now be filtered in Lua before they are display.</li>
|
||
<li>clink.quote_split().</li>
|
||
<li>clink.arg.node_merge().</li>
|
||
<li>clink.get_screen_info() (issue 71).</li>
|
||
<li>clink.split() (for splitting strings).</li>
|
||
<li>clink.chdir().</li>
|
||
<li>clink.get_cwd().</li>
|
||
<li>Functions to query Clink's settings.</li>
|
||
</ul>
|
||
</li>
|
||
<li>New command line options;<ul>
|
||
<li><code>--profile <span class="arg">dir</span></code> to override default profile directory.</li>
|
||
<li><code>--nohostcheck</code> disables verification that host is cmd.exe.</li>
|
||
<li><code>--pid</code> specifies the process to inject into.</li>
|
||
</ul>
|
||
</li>
|
||
<li>Update Mercurial completion (issue 73).</li>
|
||
<li>Start menu shortcut starts in USERPROFILE, like cmd.exe</li>
|
||
<li>Zip distribution is now portable.</li>
|
||
</ul>
|
||
<h3 id="v021">v0.2.1</h3>
|
||
<ul>
|
||
<li>The .history file now merges multiple sessions together.</li>
|
||
<li>Fixed missing y/n, pause, and other prompts.</li>
|
||
<li>Fixed segfault in loader executable.</li>
|
||
<li>Better ConEmu compatibility.</li>
|
||
</ul>
|
||
<h3 id="v02">v0.2</h3>
|
||
<ul>
|
||
<li>Basic argument completion for <code>git</code>, <code>hg</code>, <code>svn</code>, and <code>p4</code>.</li>
|
||
<li>Traditional Bash clear screen (<kbd>Ctrl</kbd>-<kbd>L</kbd>) and exit shortcuts (<kbd>Ctrl</kbd>-<kbd>D</kbd>).</li>
|
||
<li>Scrollable command window using <kbd>PgUp</kbd>/<kbd>PgDown</kbd> keys.</li>
|
||
<li>Doskey support.</li>
|
||
<li>Automatic quoting of file names with spaces.</li>
|
||
<li>Scriptable custom prompts.</li>
|
||
<li>New argument framework to ease writing context-sensitive match generators.</li>
|
||
<li>History and log file is now saved per-user rather than globally.</li>
|
||
<li>Improved Clink's command line interface (<code>clink --help</code>).</li>
|
||
<li>More reliable handling of cmd.exe's autorun entry.</li>
|
||
<li>General improvements to executable and directory-command completion.</li>
|
||
<li>Symbolic link support.</li>
|
||
<li>Documentation.</li>
|
||
<li>Windows 8 support.</li>
|
||
<li>Improved hooking so Clink can be shared with other thirdparty utilities that
|
||
also hook cmd.exe (ConEmu, ANSICon, etc.).</li>
|
||
</ul>
|
||
<h3 id="v011">v0.1.1</h3>
|
||
<ul>
|
||
<li>Fixed <kbd>AltGr</kbd>+<kbd><key></kbd> on international keyboards.</li>
|
||
<li>Fixed broken completion when directories have a <code>-</code> in their name (Mark Hammond)</li>
|
||
<li>The check for single match scenarios now correctly handles case-insensitivity.</li>
|
||
</ul>
|
||
<h3 id="v01">v0.1</h3>
|
||
<ul>
|
||
<li>Initial release.</li>
|
||
</ul>
|
||
<!-- vim: wrap nolist ft=markdown
|
||
-->
|
||
|
||
</div>
|
||
<div class="section" id="credits">
|
||
<h1 id="license">License</h1>
|
||
<p>Clink is distributed under the terms of the <a href="http://www.gnu.org/licenses/gpl.html">GNU General Public License, version 3</a>.</p>
|
||
<h1 id="credits">Credits</h1>
|
||
<h3 id="clink">Clink</h3>
|
||
<p>Clink was originally built by Martin Ridgers (<a href="https://github.com/mridgers/clink">https://github.com/mridgers/clink</a>).<br/>
|
||
Copyright (c) 2012-2018 by Martin Ridgers.</p>
|
||
<p>Clink has been forked and renovated by Christopher Antos (<a href="https://github.com/chrisant996/clink">https://github.com/chrisant996/clink</a>).<br/>
|
||
Portions Copyright (c) 2020-2021 by Christopher Antos.</p>
|
||
<h3 id="libraries">Libraries</h3>
|
||
<p>GNU Readline library version 8.1 (<a href="https://tiswww.case.edu/php/chet/readline/rltop.html">https://tiswww.case.edu/php/chet/readline/rltop.html</a>).<br/>
|
||
GNU Readline is distributed under the terms of the <a href="http://www.gnu.org/licenses/gpl.html">GNU General Public License, version 3</a>.</p>
|
||
<p>Lua 5.2 (<a href="https://www.lua.org">https://www.lua.org</a>).</p>
|
||
<p>getopt library.<br/>
|
||
Copyright (c) 1997 Gregory Pietsch, placed in the public domain.</p>
|
||
<p>Detours library version 4.0.1 (<a href="https://github.com/microsoft/detours">https://github.com/microsoft/detours</a>).<br/>
|
||
Copyright (c) Microsoft Corporation. All rights reserved.<br/>
|
||
Licensed under the <a href="https://github.com/microsoft/Detours/blob/e5400b4ec59478cb0f435cf3b1338226bcbe28f6/LICENSE.txt">MIT</a> license.</p>
|
||
<p>Clink documentation embeds the highlight.js library (<a href="https://highlightjs.org">https://highlightjs.org</a>).<br/>
|
||
Highlight.js is released under the <a href="https://github.com/highlightjs/highlight.js/blob/master/LICENSE">BSD License</a>.</p>
|
||
</div>
|
||
</div>
|
||
</body>
|
||
|
||
</html>
|