Merge branch 'master' into ranked-word-completion
This commit is contained in:
commit
2eba789610
|
@ -787,6 +787,7 @@ attributes is a string of letters each defining an attributes:
|
|||
* `B`: Blink
|
||||
* `d`: Dim
|
||||
* `i`: Italic
|
||||
* `e`: Exclusive, override previous faces instead of merging with them
|
||||
|
||||
Using named faces instead of facespec permits to change the effective faces
|
||||
afterwards.
|
||||
|
|
|
@ -68,17 +68,6 @@ def -hidden _c-family-indent-on-closing-curly-brace %[
|
|||
try %[ exec -draft "hm;<a-?>(class|struct|union)<ret><a-k>\`(class|struct|union)[^{}\n]+(\n)?\s*\{\'<ret><a-;>ma;<esc>" ]
|
||||
]
|
||||
|
||||
decl str c_astyle_options ""
|
||||
def c-format-astyle -docstring "Format C/C++/Obj-C code using the astyle utility" %{
|
||||
%sh{
|
||||
readonly x=$((kak_cursor_column - 1))
|
||||
readonly y="${kak_cursor_line}"
|
||||
|
||||
echo "exec -draft %{%|astyle<space>${kak_opt_c_astyle_options// /<space>}<ret>}"
|
||||
echo "exec gg ${y}g ${x}l"
|
||||
}
|
||||
}
|
||||
|
||||
# Regions definition are the same between c++ and objective-c
|
||||
%sh{
|
||||
for ft in c cpp objc; do
|
||||
|
@ -135,7 +124,7 @@ hook global WinSetOption filetype=(c|cpp|objc) %[
|
|||
alias window comment-selection c-family-comment-selection
|
||||
alias window comment-line c-family-comment-line
|
||||
|
||||
alias window format-code c-format-astyle
|
||||
set window formatcmd "astyle"
|
||||
]
|
||||
|
||||
hook global WinSetOption filetype=(?!(c|cpp|objc)$).* %[
|
||||
|
@ -145,8 +134,6 @@ hook global WinSetOption filetype=(?!(c|cpp|objc)$).* %[
|
|||
unalias window alt c-family-alternative-file
|
||||
unalias window comment-selection c-family-comment-selection
|
||||
unalias window comment-line c-family-comment-line
|
||||
|
||||
unalias window format-code c-format-astyle
|
||||
]
|
||||
|
||||
hook global WinSetOption filetype=c %[ addhl ref c ]
|
||||
|
|
15
rc/dlang.kak
15
rc/dlang.kak
|
@ -70,17 +70,6 @@ def -hidden _dlang-indent-on-closing-curly-brace %[
|
|||
try %[ exec -itersel -draft <a-h><a-k>^\h+\}$<ret>hms\`|.\'<ret>1<a-&> ]
|
||||
]
|
||||
|
||||
decl str dlang_dfmt_options ""
|
||||
def dlang-format-dfmt -docstring "Format the code using the dfmt utility" %{
|
||||
%sh{
|
||||
readonly x=$((kak_cursor_column - 1))
|
||||
readonly y="${kak_cursor_line}"
|
||||
|
||||
echo "exec -draft %{%|dfmt<space>${kak_opt_dlang_dfmt_options// /<space>}<ret>}"
|
||||
echo "exec gg ${y}g ${x}l"
|
||||
}
|
||||
}
|
||||
|
||||
# Initialization
|
||||
# ‾‾‾‾‾‾‾‾‾‾‾‾‾‾
|
||||
|
||||
|
@ -93,7 +82,7 @@ hook global WinSetOption filetype=dlang %{
|
|||
hook window InsertChar \{ -group dlang-indent _dlang-indent-on-opening-curly-brace
|
||||
hook window InsertChar \} -group dlang-indent _dlang-indent-on-closing-curly-brace
|
||||
|
||||
alias window format-code dlang-format-dfmt
|
||||
set window formatcmd "dfmt"
|
||||
}
|
||||
|
||||
hook global WinSetOption filetype=(?!dlang).* %{
|
||||
|
@ -101,6 +90,4 @@ hook global WinSetOption filetype=(?!dlang).* %{
|
|||
|
||||
rmhooks window dlang-hooks
|
||||
rmhooks window dlang-indent
|
||||
|
||||
unalias window format-code dlang-format-dfmt
|
||||
}
|
||||
|
|
14
rc/formatter.kak
Normal file
14
rc/formatter.kak
Normal file
|
@ -0,0 +1,14 @@
|
|||
decl str formatcmd ""
|
||||
def format -docstring "Format the entire buffer with an external utility" %{
|
||||
%sh{
|
||||
if [ ! -z "${kak_opt_formatcmd}" ]; then
|
||||
## Save the current position of the cursor
|
||||
readonly x=$((kak_cursor_column - 1))
|
||||
readonly y="${kak_cursor_line}"
|
||||
|
||||
echo "exec -draft %{%|${kak_opt_formatcmd// /<space>}<ret>}"
|
||||
## Try to restore the position of the cursor as it was prior to formatting
|
||||
echo "exec gg ${y}g ${x}l"
|
||||
fi
|
||||
}
|
||||
}
|
|
@ -62,16 +62,6 @@ def -hidden _golang-indent-on-closing-curly-brace %[
|
|||
try %[ exec -itersel -draft <a-h><a-k>^\h+\}$<ret>hms\`|.\'<ret>1<a-&> ]
|
||||
]
|
||||
|
||||
def golang-format-gofmt -docstring "Format the code using the gofmt utility" %{
|
||||
%sh{
|
||||
readonly x=$((kak_cursor_column - 1))
|
||||
readonly y="${kak_cursor_line}"
|
||||
|
||||
echo "exec -draft %{%|gofmt<ret>}"
|
||||
echo "exec gg ${y}g ${x}l"
|
||||
}
|
||||
}
|
||||
|
||||
# Initialization
|
||||
# ‾‾‾‾‾‾‾‾‾‾‾‾‾‾
|
||||
|
||||
|
@ -84,7 +74,7 @@ hook global WinSetOption filetype=golang %{
|
|||
hook window InsertChar \{ -group golang-indent _golang-indent-on-opening-curly-brace
|
||||
hook window InsertChar \} -group golang-indent _golang-indent-on-closing-curly-brace
|
||||
|
||||
alias window format-code golang-format-gofmt
|
||||
set window formatcmd "gofmt"
|
||||
}
|
||||
|
||||
hook global WinSetOption filetype=(?!golang).* %{
|
||||
|
@ -92,6 +82,4 @@ hook global WinSetOption filetype=(?!golang).* %{
|
|||
|
||||
rmhooks window golang-hooks
|
||||
rmhooks window golang-indent
|
||||
|
||||
unalias window format-code golang-format-gofmt
|
||||
}
|
||||
|
|
118
rc/perl.kak
Normal file
118
rc/perl.kak
Normal file
|
@ -0,0 +1,118 @@
|
|||
# https://www.perl.org/
|
||||
# ‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾
|
||||
|
||||
# Detection
|
||||
# ‾‾‾‾‾‾‾‾‾
|
||||
|
||||
hook global BufSetOption mimetype=text/x-perl %{
|
||||
set buffer filetype perl
|
||||
}
|
||||
|
||||
hook global BufCreate .*\.pl %{
|
||||
set buffer filetype perl
|
||||
}
|
||||
|
||||
# Highlighters
|
||||
# ‾‾‾‾‾‾‾‾‾‾‾‾
|
||||
|
||||
addhl -group / regions -default code perl \
|
||||
command '(?:[^\$]|^)`' '`' '' \
|
||||
command '\<qx/' (?<!\\)(\\\\)*/ '' \
|
||||
double_string '(?:[^\$]|^)"' (?<!\\)(\\\\)*" '' \
|
||||
double_string '\<q(q|w)/' (?<!\\)(\\\\)*/ '' \
|
||||
single_string "(?:[^\$]|^)'" (?<!\\)(\\\\)*' '' \
|
||||
single_string "\<q/" (?<!\\)(\\\\)*/ '' \
|
||||
comment '(?:[^\$]|^)#' $ ''
|
||||
|
||||
addhl -group /perl/command fill magenta
|
||||
addhl -group /perl/double_string fill string
|
||||
addhl -group /perl/single_string fill string
|
||||
addhl -group /perl/comment fill comment
|
||||
|
||||
addhl -group /perl/code regex \<__(DATA|END|FILE|LINE|PACKAGE)__\> 0:value
|
||||
addhl -group /perl/code regex \<(ARGV|STDERR|STDOUT|ARGVOUT|STDIN)\> 0:value
|
||||
addhl -group /perl/code regex (?!\$)-?([0-9]*\.(?!0[xXbB]))?\<([0-9]+|0[xX][0-9a-fA-F]+|0[bb][01_]+)\.?([eE][+-]?[0-9]+)?i?\> 0:value
|
||||
addhl -group /perl/code regex %{\$!|\$"|\$#|\$\$|\$%|\$&|\$'|\$\(|\$\)|\$\*|\$\+|\$,|\$_|\$-|\$`|\$\.|\$/|\$:|\$;|\$<|\$=|\$>|\$\?|\$@|\$\[|\$\\|\$\]|\$\^|\$\||\$~|%!|@\+|@-|@_} 0:value
|
||||
addhl -group /perl/code regex (%ENV|%INC|%OVERLOAD|%SIG|@ARGV|@INC|@LAST_MATCH_START) 0:value
|
||||
addhl -group /perl/code regex %{%\^(H)\>} 0:value
|
||||
addhl -group /perl/code regex \$\^(S|T|V|W|X|A|C|D|E|F|H|I|L|M|N|O|P|R)\> 0:value
|
||||
addhl -group /perl/code regex \$\^(RE_TRIE_MAXBUF|TAINT|UNICODE|UTF8LOCALE|WARNING_BITS|WIDE_SYSTEM_CALLS|CHILD_ERROR_NATIVE|ENCODING|OPEN|RE_DEBUG_FLAGS)\> 0:value
|
||||
|
||||
addhl -group /perl/code regex \$[0-9]+ 0:attribute
|
||||
addhl -group /perl/code regex \<-(B|b|C|c|d|e|f|g|k|l|M|O|o|p|r|R|S|s|T|t|u|w|W|X|x|z)\> 0:attribute
|
||||
addhl -group /perl/code regex \<(END|AUTOLOAD|BEGIN|CHECK|UNITCHECK|INIT|DESTROY)\> 0:attribute
|
||||
addhl -group /perl/code regex \<(length|setpgrp|endgrent|link|setpriority|endhostent|listen|setprotoent|endnetent|local|setpwent)\> 0:attribute
|
||||
addhl -group /perl/code regex \<(endprotoent|localtime|setservent|endpwent|log|setsockopt|endservent|lstat|shift|eof|map|shmctl|eval|mkdir|shmget|exec|msgctl|shmread)\> 0:attribute
|
||||
addhl -group /perl/code regex \<(exists|msgget|shmwrite|msgrcv|shutdown|fcntl|msgsnd|sin|fileno|sleep|flock|next|socket|fork|socketpair|format|oct|sort)\> 0:attribute
|
||||
addhl -group /perl/code regex \<(formline|open|splice|getc|opendir|split|getgrent|ord|sprintf|getgrgid|our|sqrt|getgrnam|pack|srand|gethostbyaddr|pipe|stat|gethostbyname)\> 0:attribute
|
||||
addhl -group /perl/code regex \<(pop|state|gethostent|pos|study|getlogin|print|substr|getnetbyaddr|printf|symlink|abs|getnetbyname|prototype|syscall|accept|getnetent)\> 0:attribute
|
||||
addhl -group /perl/code regex \<(push|sysopen|alarm|getpeername|quotemeta|sysread|atan2|getpgrp|rand|sysseek|getppid|read|system|getpriority|readdir|syswrite|bind)\> 0:attribute
|
||||
addhl -group /perl/code regex \<(getprotobyname|readline|tell|binmode|getprotobynumber|readlink|telldir|bless|getprotoent|readpipe|tie|getpwent|recv|tied|caller)\> 0:attribute
|
||||
addhl -group /perl/code regex \<(getpwnam|redo|time|chdir|getpwuid|ref|times|getservbyname|rename|truncate|chmod|getservbyport|require|uc|chomp|getservent|reset|ucfirst)\> 0:attribute
|
||||
addhl -group /perl/code regex \<(chop|getsockname|umask|chown|getsockopt|reverse|undef|chr|glob|rewinddir|chroot|gmtime|rindex|unlink|close|rmdir|unpack)\> 0:attribute
|
||||
addhl -group /perl/code regex \<(closedir|grep|say|unshift|connect|hex|scalar|untie|cos|index|seek|use|crypt|seekdir|utime|dbmclose|int|select|values|dbmopen|ioctl|semctl)\> 0:attribute
|
||||
addhl -group /perl/code regex \<(vec|defined|join|semget|wait|delete|keys|semop|waitpid|kill|send|wantarray|die|last|setgrent|warn|dump|lc|sethostent|write|each|lcfirst|setnetent)\> 0:attribute
|
||||
|
||||
addhl -group /perl/code regex \<(else|lock|qw|elsif|lt|qx|eq||exp|ne|sub|for|no|my|not|tr|goto|and|foreach|or|break|exit|unless|cmp|ge|package|until|continue|gt|while|if|qq|xor|do|le|qr|return)\> 0:keyword
|
||||
|
||||
addhl -group /perl/code regex %{(?:\<[stqrmwy]+)?/[^\n/]*/([msixpodualngecr]+\>)?} 0:magenta
|
||||
addhl -group /perl/code regex %{(?:\<[stqrmwy]+)?/[^\n/]+/[^\n/]*/([msixpeodualngcr]+\>)?} 0:magenta
|
||||
|
||||
addhl -group /perl/code regex \$[a-zA-Z_][a-zA-Z0-9_]* 0:blue
|
||||
|
||||
addhl -group /perl/code regex \$(a|b|LAST_REGEXP_CODE_RESULT|LIST_SEPARATOR|MATCH|MULTILINE_MATCHING|NR|OFMT|OFS|ORS|OS_ERROR|OSNAME|OUTPUT_AUTO_FLUSH|OUTPUT_FIELD_SEPARATOR|OUTPUT_RECORD_SEPARATOR)\> 0:value
|
||||
addhl -group /perl/code regex \$(LAST_REGEXP_CODE_RESULT|LIST_SEPARATOR|MATCH|MULTILINE_MATCHING|NR|OFMT|OFS|ORS|OS_ERROR|OSNAME|OUTPUT_AUTO_FLUSH|OUTPUT_FIELD_SEPARATOR|OUTPUT_RECORD_SEPARATOR|PERL_VERSION|ACCUMULATOR|PERLDB|ARG|PID|ARGV|POSTMATCH|PREMATCH|BASETIME|PROCESS_ID|CHILD_ERROR|PROGRAM_NAME|COMPILING|REAL_GROUP_ID|DEBUGGING|REAL_USER_ID|EFFECTIVE_GROUP_ID|RS|EFFECTIVE_USER_ID|SUBSCRIPT_SEPARATOR|EGID|SUBSEP|ERRNO|SYSTEM_FD_MAX|EUID|UID|EVAL_ERROR|WARNING|EXCEPTIONS_BEING_CAUGHT|EXECUTABLE_NAME|EXTENDED_OS_ERROR|FORMAT_FORMFEED|FORMAT_LINE_BREAK_CHARACTERS|FORMAT_LINES_LEFT|FORMAT_LINES_PER_PAGE|FORMAT_NAME|FORMAT_PAGE_NUMBER|FORMAT_TOP_NAME|GID|INPLACE_EDIT|INPUT_LINE_NUMBER|INPUT_RECORD_SEPARATOR|LAST_MATCH_END|LAST_PAREN_MATCH)\> 0:value
|
||||
|
||||
# Commands
|
||||
# ‾‾‾‾‾‾‾‾
|
||||
|
||||
def -hidden _perl-indent-on-new-line %~
|
||||
eval -draft -itersel %=
|
||||
# preserve previous line indent
|
||||
try %{ exec -draft \;K<a-&> }
|
||||
# indent after lines ending with { or (
|
||||
try %[ exec -draft k<a-x> <a-k> [{(]\h*$ <ret> j<a-gt> ]
|
||||
# cleanup trailing white spaces on the previous line
|
||||
try %{ exec -draft k<a-x> s \h+$ <ret>d }
|
||||
# align to opening paren of previous line
|
||||
try %{ exec -draft [( <a-k> \`\([^\n]+\n[^\n]*\n?\' <ret> s \`\(\h*.|.\' <ret> '<a-;>' & }
|
||||
# copy // comments prefix
|
||||
try %{ exec -draft \;<c-s>k<a-x> s ^\h*\K/{2,} <ret> y<c-o><c-o>P<esc> }
|
||||
# indent after a switch's case/default statements
|
||||
try %[ exec -draft k<a-x> <a-k> ^\h*(case|default).*:$ <ret> j<a-gt> ]
|
||||
# indent after if|else|while|for
|
||||
try %[ exec -draft \;<a-F>)MB <a-k> \`(if|else|while|for)\h*\(.*\)\h*\n\h*\n?\' <ret> s \`|.\' <ret> 1<a-&>1<a-space><a-gt> ]
|
||||
=
|
||||
~
|
||||
|
||||
def -hidden _perl-indent-on-opening-curly-brace %[
|
||||
# align indent with opening paren when { is entered on a new line after the closing paren
|
||||
try %[ exec -draft -itersel h<a-F>)M <a-k> \`\(.*\)\h*\n\h*\{\' <ret> s \`|.\' <ret> 1<a-&> ]
|
||||
]
|
||||
|
||||
def -hidden _perl-indent-on-closing-curly-brace %[
|
||||
# align to opening curly brace when alone on a line
|
||||
try %[ exec -itersel -draft <a-h><a-k>^\h+\}$<ret>hms\`|.\'<ret>1<a-&> ]
|
||||
]
|
||||
|
||||
# Initialization
|
||||
# ‾‾‾‾‾‾‾‾‾‾‾‾‾‾
|
||||
|
||||
hook global WinSetOption filetype=perl %{
|
||||
addhl ref perl
|
||||
|
||||
# cleanup trailing whitespaces when exiting insert mode
|
||||
hook window InsertEnd .* -group perl-hooks %{ try %{ exec -draft <a-x>s^\h+$<ret>d } }
|
||||
hook window InsertChar \n -group perl-indent _perl-indent-on-new-line
|
||||
hook window InsertChar \{ -group perl-indent _perl-indent-on-opening-curly-brace
|
||||
hook window InsertChar \} -group perl-indent _perl-indent-on-closing-curly-brace
|
||||
|
||||
set window formatcmd "perltidy"
|
||||
}
|
||||
|
||||
hook global WinSetOption filetype=(?!perl).* %{
|
||||
rmhl perl
|
||||
|
||||
rmhooks window perl-hooks
|
||||
rmhooks window perl-indent
|
||||
}
|
|
@ -310,7 +310,7 @@ TokenList parse(StringView line)
|
|||
|
||||
if (not str.empty())
|
||||
result.emplace_back(Token::Type::Raw, start, reader.pos,
|
||||
coord, std::move(unescape(str, "%", '\\')));
|
||||
coord, unescape(str, "%", '\\'));
|
||||
}
|
||||
|
||||
if (is_command_separator(*reader))
|
||||
|
@ -323,8 +323,7 @@ TokenList parse(StringView line)
|
|||
}
|
||||
|
||||
String expand_token(const Token& token, const Context& context,
|
||||
ConstArrayView<String> shell_params,
|
||||
const EnvVarMap& env_vars)
|
||||
const ShellContext& shell_context)
|
||||
{
|
||||
auto& content = token.content();
|
||||
switch (token.type())
|
||||
|
@ -332,20 +331,20 @@ String expand_token(const Token& token, const Context& context,
|
|||
case Token::Type::ShellExpand:
|
||||
return ShellManager::instance().eval(content, context, {},
|
||||
ShellManager::Flags::WaitForStdout,
|
||||
shell_params, env_vars).first;
|
||||
shell_context).first;
|
||||
case Token::Type::RegisterExpand:
|
||||
return context.main_sel_register_value(content).str();
|
||||
case Token::Type::OptionExpand:
|
||||
return context.options()[content].get_as_string();
|
||||
case Token::Type::ValExpand:
|
||||
{
|
||||
auto it = env_vars.find(content);
|
||||
if (it != env_vars.end())
|
||||
auto it = shell_context.env_vars.find(content);
|
||||
if (it != shell_context.env_vars.end())
|
||||
return it->value;
|
||||
return ShellManager::instance().get_val(content, context);
|
||||
}
|
||||
case Token::Type::RawEval:
|
||||
return expand(content, context, shell_params, env_vars);
|
||||
return expand(content, context, shell_context);
|
||||
case Token::Type::Raw:
|
||||
case Token::Type::RawQuoted:
|
||||
return content;
|
||||
|
@ -357,8 +356,7 @@ String expand_token(const Token& token, const Context& context,
|
|||
}
|
||||
|
||||
String expand(StringView str, const Context& context,
|
||||
ConstArrayView<String> shell_params,
|
||||
const EnvVarMap& env_vars)
|
||||
const ShellContext& shell_context)
|
||||
{
|
||||
Reader reader{str};
|
||||
String res;
|
||||
|
@ -380,7 +378,7 @@ String expand(StringView str, const Context& context,
|
|||
{
|
||||
res += reader.substr_from(beg);
|
||||
Token token = parse_percent_token<true>(reader);
|
||||
res += expand_token(token, context, shell_params, env_vars);
|
||||
res += expand_token(token, context, shell_context);
|
||||
beg = (++reader).pos;
|
||||
}
|
||||
else
|
||||
|
@ -407,6 +405,7 @@ CommandManager::find_command(const Context& context, const String& name) const
|
|||
|
||||
void CommandManager::execute_single_command(CommandParameters params,
|
||||
Context& context,
|
||||
const ShellContext& shell_context,
|
||||
CharCoord pos) const
|
||||
{
|
||||
if (params.empty())
|
||||
|
@ -421,7 +420,7 @@ void CommandManager::execute_single_command(CommandParameters params,
|
|||
{
|
||||
ParametersParser parameter_parser(param_view,
|
||||
command_it->second.param_desc);
|
||||
command_it->second.command(parameter_parser, context);
|
||||
command_it->second.command(parameter_parser, context, shell_context);
|
||||
}
|
||||
catch (runtime_error& error)
|
||||
{
|
||||
|
@ -431,9 +430,7 @@ void CommandManager::execute_single_command(CommandParameters params,
|
|||
}
|
||||
|
||||
void CommandManager::execute(StringView command_line,
|
||||
Context& context,
|
||||
ConstArrayView<String> shell_params,
|
||||
const EnvVarMap& env_vars)
|
||||
Context& context, const ShellContext& shell_context)
|
||||
{
|
||||
TokenList tokens = parse<true>(command_line);
|
||||
if (tokens.empty())
|
||||
|
@ -448,15 +445,14 @@ void CommandManager::execute(StringView command_line,
|
|||
|
||||
if (it->type() == Token::Type::CommandSeparator)
|
||||
{
|
||||
execute_single_command(params, context, command_coord);
|
||||
execute_single_command(params, context, shell_context, command_coord);
|
||||
params.clear();
|
||||
}
|
||||
// Shell expand are retokenized
|
||||
else if (it->type() == Token::Type::ShellExpand)
|
||||
{
|
||||
auto shell_tokens = parse<true>(expand_token(*it, context,
|
||||
shell_params,
|
||||
env_vars));
|
||||
shell_context));
|
||||
it = tokens.erase(it);
|
||||
for (Token& token : shell_tokens)
|
||||
it = ++tokens.emplace(it, std::move(token));
|
||||
|
@ -467,10 +463,9 @@ void CommandManager::execute(StringView command_line,
|
|||
it -= shell_tokens.size() + 1;
|
||||
}
|
||||
else
|
||||
params.push_back(expand_token(*it, context, shell_params,
|
||||
env_vars));
|
||||
params.push_back(expand_token(*it, context, shell_context));
|
||||
}
|
||||
execute_single_command(params, context, command_coord);
|
||||
execute_single_command(params, context, shell_context, command_coord);
|
||||
}
|
||||
|
||||
CommandInfo CommandManager::command_info(const Context& context, StringView command_line) const
|
||||
|
|
|
@ -19,11 +19,15 @@ namespace Kakoune
|
|||
|
||||
class Context;
|
||||
using CommandParameters = ConstArrayView<String>;
|
||||
using Command = std::function<void (const ParametersParser& parser, Context& context)>;
|
||||
using Command = std::function<void (const ParametersParser& parser,
|
||||
Context& context,
|
||||
const ShellContext& shell_context)>;
|
||||
|
||||
using CommandCompleter = std::function<Completions (const Context& context,
|
||||
CompletionFlags,
|
||||
CommandParameters,
|
||||
size_t, ByteCount)>;
|
||||
|
||||
using CommandHelper = std::function<String (const Context& context, CommandParameters)>;
|
||||
|
||||
enum class CommandFlags
|
||||
|
@ -61,8 +65,7 @@ class CommandManager : public Singleton<CommandManager>
|
|||
{
|
||||
public:
|
||||
void execute(StringView command_line, Context& context,
|
||||
ConstArrayView<String> shell_params = {},
|
||||
const EnvVarMap& env_vars = EnvVarMap{});
|
||||
const ShellContext& shell_context = ShellContext{});
|
||||
|
||||
Completions complete(const Context& context, CompletionFlags flags,
|
||||
StringView command_line, ByteCount cursor_pos);
|
||||
|
@ -85,7 +88,9 @@ public:
|
|||
|
||||
private:
|
||||
void execute_single_command(CommandParameters params,
|
||||
Context& context, CharCoord pos) const;
|
||||
Context& context,
|
||||
const ShellContext& shell_context,
|
||||
CharCoord pos) const;
|
||||
|
||||
struct CommandDescriptor
|
||||
{
|
||||
|
@ -104,8 +109,7 @@ private:
|
|||
};
|
||||
|
||||
String expand(StringView str, const Context& context,
|
||||
ConstArrayView<String> shell_params = {},
|
||||
const EnvVarMap& env_vars = EnvVarMap{});
|
||||
const ShellContext& shell_context = ShellContext{});
|
||||
|
||||
}
|
||||
|
||||
|
|
139
src/commands.cc
139
src/commands.cc
|
@ -120,11 +120,11 @@ struct CommandDesc
|
|||
CommandFlags flags;
|
||||
CommandHelper helper;
|
||||
CommandCompleter completer;
|
||||
void (*func)(const ParametersParser&, Context&);
|
||||
void (*func)(const ParametersParser&, Context&, const ShellContext&);
|
||||
};
|
||||
|
||||
template<bool force_reload>
|
||||
void edit(const ParametersParser& parser, Context& context)
|
||||
void edit(const ParametersParser& parser, Context& context, const ShellContext&)
|
||||
{
|
||||
if (parser.positional_count() == 0 and not force_reload)
|
||||
throw wrong_argument_count();
|
||||
|
@ -215,7 +215,7 @@ const CommandDesc force_edit_cmd = {
|
|||
edit<true>
|
||||
};
|
||||
|
||||
void write_buffer(const ParametersParser& parser, Context& context)
|
||||
void write_buffer(const ParametersParser& parser, Context& context, const ShellContext&)
|
||||
{
|
||||
Buffer& buffer = context.buffer();
|
||||
|
||||
|
@ -256,7 +256,7 @@ const CommandDesc writeall_cmd = {
|
|||
CommandFlags::None,
|
||||
CommandHelper{},
|
||||
CommandCompleter{},
|
||||
[](const ParametersParser&, Context&){ write_all_buffers(); }
|
||||
[](const ParametersParser&, Context&, const ShellContext&){ write_all_buffers(); }
|
||||
};
|
||||
|
||||
const CommandDesc kill_cmd = {
|
||||
|
@ -267,7 +267,7 @@ const CommandDesc kill_cmd = {
|
|||
CommandFlags::None,
|
||||
CommandHelper{},
|
||||
CommandCompleter{},
|
||||
[](const ParametersParser&, Context&){ throw kill_session{}; }
|
||||
[](const ParametersParser&, Context&, const ShellContext&){ throw kill_session{}; }
|
||||
};
|
||||
|
||||
template<bool force>
|
||||
|
@ -307,7 +307,7 @@ const CommandDesc quit_cmd = {
|
|||
CommandFlags::None,
|
||||
CommandHelper{},
|
||||
CommandCompleter{},
|
||||
[](const ParametersParser&, Context&){ quit<false>(); }
|
||||
[](const ParametersParser&, Context&, const ShellContext&){ quit<false>(); }
|
||||
};
|
||||
|
||||
const CommandDesc force_quit_cmd = {
|
||||
|
@ -320,7 +320,7 @@ const CommandDesc force_quit_cmd = {
|
|||
CommandFlags::None,
|
||||
CommandHelper{},
|
||||
CommandCompleter{},
|
||||
[](const ParametersParser&, Context&){ quit<true>(); }
|
||||
[](const ParametersParser&, Context&, const ShellContext&){ quit<true>(); }
|
||||
};
|
||||
|
||||
const CommandDesc write_quit_cmd = {
|
||||
|
@ -331,9 +331,9 @@ const CommandDesc write_quit_cmd = {
|
|||
CommandFlags::None,
|
||||
CommandHelper{},
|
||||
CommandCompleter{},
|
||||
[](const ParametersParser& parser, Context& context)
|
||||
[](const ParametersParser& parser, Context& context, const ShellContext& shell_context)
|
||||
{
|
||||
write_buffer(parser, context);
|
||||
write_buffer(parser, context, shell_context);
|
||||
quit<false>();
|
||||
}
|
||||
};
|
||||
|
@ -347,9 +347,9 @@ const CommandDesc force_write_quit_cmd = {
|
|||
CommandFlags::None,
|
||||
CommandHelper{},
|
||||
CommandCompleter{},
|
||||
[](const ParametersParser& parser, Context& context)
|
||||
[](const ParametersParser& parser, Context& context, const ShellContext& shell_context)
|
||||
{
|
||||
write_buffer(parser, context);
|
||||
write_buffer(parser, context, shell_context);
|
||||
quit<true>();
|
||||
}
|
||||
};
|
||||
|
@ -362,7 +362,7 @@ const CommandDesc writeall_quit_cmd = {
|
|||
CommandFlags::None,
|
||||
CommandHelper{},
|
||||
CommandCompleter{},
|
||||
[](const ParametersParser& parser, Context& context)
|
||||
[](const ParametersParser& parser, Context& context, const ShellContext&)
|
||||
{
|
||||
write_all_buffers();
|
||||
quit<false>();
|
||||
|
@ -377,7 +377,7 @@ const CommandDesc buffer_cmd = {
|
|||
CommandFlags::None,
|
||||
CommandHelper{},
|
||||
buffer_completer,
|
||||
[](const ParametersParser& parser, Context& context)
|
||||
[](const ParametersParser& parser, Context& context, const ShellContext&)
|
||||
{
|
||||
Buffer* oldbuf = &context.buffer();
|
||||
Buffer& buffer = BufferManager::instance().get_buffer(parser[0]);
|
||||
|
@ -392,7 +392,7 @@ const CommandDesc buffer_cmd = {
|
|||
};
|
||||
|
||||
template<bool next>
|
||||
void cycle_buffer(const ParametersParser& parser, Context& context)
|
||||
void cycle_buffer(const ParametersParser& parser, Context& context, const ShellContext&)
|
||||
{
|
||||
Buffer* oldbuf = &context.buffer();
|
||||
auto it = find_if(BufferManager::instance(),
|
||||
|
@ -446,7 +446,7 @@ const CommandDesc bufferprev_cmd = {
|
|||
};
|
||||
|
||||
template<bool force>
|
||||
void delete_buffer(const ParametersParser& parser, Context& context)
|
||||
void delete_buffer(const ParametersParser& parser, Context& context, const ShellContext&)
|
||||
{
|
||||
BufferManager& manager = BufferManager::instance();
|
||||
Buffer& buffer = parser.positional_count() == 0 ? context.buffer() : manager.get_buffer(parser[0]);
|
||||
|
@ -490,7 +490,7 @@ const CommandDesc namebuf_cmd = {
|
|||
CommandFlags::None,
|
||||
CommandHelper{},
|
||||
CommandCompleter{},
|
||||
[](const ParametersParser& parser, Context& context)
|
||||
[](const ParametersParser& parser, Context& context, const ShellContext&)
|
||||
{
|
||||
if (not context.buffer().set_name(parser[0]))
|
||||
throw runtime_error(format("unable to change buffer name to '{}'", parser[0]));
|
||||
|
@ -585,7 +585,7 @@ const CommandDesc add_highlighter_cmd = {
|
|||
return "";
|
||||
},
|
||||
add_highlighter_completer,
|
||||
[](const ParametersParser& parser, Context& context)
|
||||
[](const ParametersParser& parser, Context& context, const ShellContext&)
|
||||
{
|
||||
HighlighterRegistry& registry = HighlighterRegistry::instance();
|
||||
|
||||
|
@ -616,7 +616,7 @@ const CommandDesc rm_highlighter_cmd = {
|
|||
CommandFlags::None,
|
||||
CommandHelper{},
|
||||
rm_highlighter_completer,
|
||||
[](const ParametersParser& parser, Context& context)
|
||||
[](const ParametersParser& parser, Context& context, const ShellContext&)
|
||||
{
|
||||
StringView path = parser[0];
|
||||
auto sep_it = find(reversed(path), '/');
|
||||
|
@ -661,7 +661,7 @@ const CommandDesc add_hook_cmd = {
|
|||
}
|
||||
return {};
|
||||
},
|
||||
[](const ParametersParser& parser, Context& context)
|
||||
[](const ParametersParser& parser, Context& context, const ShellContext&)
|
||||
{
|
||||
Regex regex(parser[2].begin(), parser[2].end(),
|
||||
Regex::optimize | Regex::nosubs | Regex::ECMAScript);
|
||||
|
@ -675,8 +675,8 @@ const CommandDesc add_hook_cmd = {
|
|||
ScopedSetBool disable_history{context.history_disabled()};
|
||||
|
||||
if (regex_match(param.begin(), param.end(), regex))
|
||||
CommandManager::instance().execute(command, context, {},
|
||||
{ { "hook_param", param.str() } });
|
||||
CommandManager::instance().execute(command, context,
|
||||
{ {}, { { "hook_param", param.str() } } });
|
||||
};
|
||||
auto group = parser.get_switch("group").value_or(StringView{});
|
||||
get_scope(parser[0], context).hooks().add_hook(parser[1], group.str(), hook_func);
|
||||
|
@ -705,7 +705,7 @@ const CommandDesc rm_hook_cmd = {
|
|||
}
|
||||
return {};
|
||||
},
|
||||
[](const ParametersParser& parser, Context& context)
|
||||
[](const ParametersParser& parser, Context& context, const ShellContext&)
|
||||
{
|
||||
get_scope(parser[0], context).hooks().remove_hooks(parser[1]);
|
||||
}
|
||||
|
@ -719,7 +719,7 @@ Vector<String> params_to_shell(const ParametersParser& parser)
|
|||
return vars;
|
||||
}
|
||||
|
||||
void define_command(const ParametersParser& parser, Context& context)
|
||||
void define_command(const ParametersParser& parser, Context& context, const ShellContext&)
|
||||
{
|
||||
const String& cmd_name = parser[0];
|
||||
auto& cm = CommandManager::instance();
|
||||
|
@ -737,14 +737,14 @@ void define_command(const ParametersParser& parser, Context& context)
|
|||
if (parser.get_switch("shell-params"))
|
||||
{
|
||||
desc = ParameterDesc{ {}, ParameterDesc::Flags::SwitchesAsPositional };
|
||||
cmd = [=](const ParametersParser& parser, Context& context) {
|
||||
CommandManager::instance().execute(commands, context, params_to_shell(parser));
|
||||
cmd = [=](const ParametersParser& parser, Context& context, const ShellContext&) {
|
||||
CommandManager::instance().execute(commands, context, { params_to_shell(parser) });
|
||||
};
|
||||
}
|
||||
else
|
||||
{
|
||||
desc = ParameterDesc{ {}, ParameterDesc::Flags::SwitchesAsPositional, 0, 0 };
|
||||
cmd = [=](const ParametersParser& parser, Context& context) {
|
||||
cmd = [=](const ParametersParser& parser, Context& context, const ShellContext&) {
|
||||
CommandManager::instance().execute(commands, context);
|
||||
};
|
||||
}
|
||||
|
@ -795,13 +795,15 @@ void define_command(const ParametersParser& parser, Context& context)
|
|||
{
|
||||
if (flags == CompletionFlags::Fast) // no shell on fast completion
|
||||
return Completions{};
|
||||
EnvVarMap vars = {
|
||||
{ "token_to_complete", to_string(token_to_complete) },
|
||||
{ "pos_in_token", to_string(pos_in_token) }
|
||||
|
||||
ShellContext shell_context{
|
||||
params,
|
||||
{ { "token_to_complete", to_string(token_to_complete) },
|
||||
{ "pos_in_token", to_string(pos_in_token) } }
|
||||
};
|
||||
String output = ShellManager::instance().eval(shell_cmd, context, {},
|
||||
ShellManager::Flags::WaitForStdout,
|
||||
params, vars).first;
|
||||
shell_context).first;
|
||||
return Completions{ 0_byte, pos_in_token, split(output, '\n', 0) };
|
||||
};
|
||||
}
|
||||
|
@ -852,7 +854,7 @@ const CommandDesc alias_cmd = {
|
|||
CommandFlags::None,
|
||||
CommandHelper{},
|
||||
CommandCompleter{},
|
||||
[](const ParametersParser& parser, Context& context)
|
||||
[](const ParametersParser& parser, Context& context, const ShellContext&)
|
||||
{
|
||||
if (not CommandManager::instance().command_defined(parser[2]))
|
||||
throw runtime_error(format("Command '{}' does not exist", parser[2]));
|
||||
|
@ -871,7 +873,7 @@ const CommandDesc unalias_cmd = {
|
|||
CommandFlags::None,
|
||||
CommandHelper{},
|
||||
CommandCompleter{},
|
||||
[](const ParametersParser& parser, Context& context)
|
||||
[](const ParametersParser& parser, Context& context, const ShellContext&)
|
||||
{
|
||||
AliasRegistry& aliases = get_scope(parser[0], context).aliases();
|
||||
if (parser.positional_count() == 3 and
|
||||
|
@ -894,7 +896,7 @@ const CommandDesc echo_cmd = {
|
|||
CommandFlags::None,
|
||||
CommandHelper{},
|
||||
CommandCompleter{},
|
||||
[](const ParametersParser& parser, Context& context)
|
||||
[](const ParametersParser& parser, Context& context, const ShellContext&)
|
||||
{
|
||||
String message = join(parser, ' ', false);
|
||||
if (parser.get_switch("debug"))
|
||||
|
@ -924,7 +926,7 @@ const CommandDesc debug_cmd = {
|
|||
auto c = {"info", "buffers", "options", "memory", "shared-strings"};
|
||||
return { 0_byte, cursor_pos, complete(prefix, cursor_pos, c) };
|
||||
} }),
|
||||
[](const ParametersParser& parser, Context& context)
|
||||
[](const ParametersParser& parser, Context& context, const ShellContext&)
|
||||
{
|
||||
if (parser[0] == "info")
|
||||
{
|
||||
|
@ -975,7 +977,7 @@ const CommandDesc source_cmd = {
|
|||
CommandFlags::None,
|
||||
CommandHelper{},
|
||||
filename_completer,
|
||||
[](const ParametersParser& parser, Context& context)
|
||||
[](const ParametersParser& parser, Context& context, const ShellContext&)
|
||||
{
|
||||
String file_content = read_file(parse_filename(parser[0]), true);
|
||||
try
|
||||
|
@ -1016,23 +1018,26 @@ const CommandDesc set_option_cmd = {
|
|||
CommandParameters params, size_t token_to_complete,
|
||||
ByteCount pos_in_token) -> Completions
|
||||
{
|
||||
if (token_to_complete == 0)
|
||||
return { 0_byte, params[0].length(),
|
||||
complete(params[0], pos_in_token, scopes) };
|
||||
else if (token_to_complete == 1)
|
||||
return { 0_byte, params[1].length(),
|
||||
GlobalScope::instance().option_registry().complete_option_name(params[1], pos_in_token) };
|
||||
else if (token_to_complete == 2 and
|
||||
GlobalScope::instance().option_registry().option_exists(params[1]))
|
||||
const bool add = params.size() > 1 and params[0] == "-add";
|
||||
const int start = add ? 1 : 0;
|
||||
|
||||
if (token_to_complete == start)
|
||||
return { 0_byte, params[start].length(),
|
||||
complete(params[start], pos_in_token, scopes) };
|
||||
else if (token_to_complete == start + 1)
|
||||
return { 0_byte, params[start + 1].length(),
|
||||
GlobalScope::instance().option_registry().complete_option_name(params[start + 1], pos_in_token) };
|
||||
else if (not add and token_to_complete == start + 2 and
|
||||
GlobalScope::instance().option_registry().option_exists(params[start + 1]))
|
||||
{
|
||||
OptionManager& options = get_scope(params[0], context).options();
|
||||
String val = options[params[1]].get_as_string();
|
||||
if (prefix_match(val, params[2]))
|
||||
return { 0_byte, params[2].length(), { std::move(val) } };
|
||||
OptionManager& options = get_scope(params[start], context).options();
|
||||
String val = options[params[start + 1]].get_as_string();
|
||||
if (prefix_match(val, params[start + 2]))
|
||||
return { 0_byte, params[start + 2].length(), { std::move(val) } };
|
||||
}
|
||||
return Completions{};
|
||||
},
|
||||
[](const ParametersParser& parser, Context& context)
|
||||
[](const ParametersParser& parser, Context& context, const ShellContext&)
|
||||
{
|
||||
Option& opt = get_scope(parser[0], context).options().get_local_option(parser[1]);
|
||||
if (parser.get_switch("add"))
|
||||
|
@ -1063,7 +1068,7 @@ const CommandDesc unset_option_cmd = {
|
|||
GlobalScope::instance().option_registry().complete_option_name(params[1], pos_in_token) };
|
||||
return Completions{};
|
||||
},
|
||||
[](const ParametersParser& parser, Context& context)
|
||||
[](const ParametersParser& parser, Context& context, const ShellContext&)
|
||||
{
|
||||
if (parser[0] == "global")
|
||||
throw runtime_error("Cannot unset options in global scope");
|
||||
|
@ -1093,7 +1098,7 @@ const CommandDesc declare_option_cmd = {
|
|||
CommandFlags::None,
|
||||
CommandHelper{},
|
||||
CommandCompleter{},
|
||||
[](const ParametersParser& parser, Context& context)
|
||||
[](const ParametersParser& parser, Context& context, const ShellContext&)
|
||||
{
|
||||
Option* opt = nullptr;
|
||||
|
||||
|
@ -1171,7 +1176,7 @@ const CommandDesc map_key_cmd = {
|
|||
}
|
||||
return {};
|
||||
},
|
||||
[](const ParametersParser& parser, Context& context)
|
||||
[](const ParametersParser& parser, Context& context, const ShellContext&)
|
||||
{
|
||||
KeymapManager& keymaps = get_scope(parser[0], context).keymaps();
|
||||
KeymapMode keymap_mode = parse_keymap_mode(parser[1]);
|
||||
|
@ -1311,7 +1316,7 @@ const CommandDesc exec_string_cmd = {
|
|||
CommandFlags::None,
|
||||
CommandHelper{},
|
||||
CommandCompleter{},
|
||||
[](const ParametersParser& parser, Context& context)
|
||||
[](const ParametersParser& parser, Context& context, const ShellContext&)
|
||||
{
|
||||
context_wrap(parser, context, [](const ParametersParser& parser, Context& context) {
|
||||
KeyList keys;
|
||||
|
@ -1333,7 +1338,7 @@ const CommandDesc eval_string_cmd = {
|
|||
CommandFlags::None,
|
||||
CommandHelper{},
|
||||
CommandCompleter{},
|
||||
[](const ParametersParser& parser, Context& context)
|
||||
[](const ParametersParser& parser, Context& context, const ShellContext&)
|
||||
{
|
||||
context_wrap(parser, context, [](const ParametersParser& parser, Context& context) {
|
||||
String command = join(parser, ' ', false);
|
||||
|
@ -1354,7 +1359,7 @@ const CommandDesc prompt_cmd = {
|
|||
CommandFlags::None,
|
||||
CommandHelper{},
|
||||
CommandCompleter{},
|
||||
[](const ParametersParser& params, Context& context)
|
||||
[](const ParametersParser& params, Context& context, const ShellContext&)
|
||||
{
|
||||
if (params[1].length() != 1)
|
||||
throw runtime_error("register name should be a single character");
|
||||
|
@ -1388,7 +1393,7 @@ const CommandDesc menu_cmd = {
|
|||
CommandFlags::None,
|
||||
CommandHelper{},
|
||||
CommandCompleter{},
|
||||
[](const ParametersParser& parser, Context& context)
|
||||
[](const ParametersParser& parser, Context& context, const ShellContext&)
|
||||
{
|
||||
const bool with_select_cmds = (bool)parser.get_switch("select-cmds");
|
||||
const bool markup = (bool)parser.get_switch("markup");
|
||||
|
@ -1434,7 +1439,7 @@ const CommandDesc onkey_cmd = {
|
|||
CommandFlags::None,
|
||||
CommandHelper{},
|
||||
CommandCompleter{},
|
||||
[](const ParametersParser& parser, Context& context)
|
||||
[](const ParametersParser& parser, Context& context, const ShellContext&)
|
||||
{
|
||||
String reg = parser[0];
|
||||
String command = parser[1];
|
||||
|
@ -1459,7 +1464,7 @@ const CommandDesc info_cmd = {
|
|||
CommandFlags::None,
|
||||
CommandHelper{},
|
||||
CommandCompleter{},
|
||||
[](const ParametersParser& parser, Context& context)
|
||||
[](const ParametersParser& parser, Context& context, const ShellContext&)
|
||||
{
|
||||
context.ui().info_hide();
|
||||
if (parser.positional_count() > 0)
|
||||
|
@ -1501,7 +1506,7 @@ const CommandDesc try_catch_cmd = {
|
|||
CommandFlags::None,
|
||||
CommandHelper{},
|
||||
CommandCompleter{},
|
||||
[](const ParametersParser& parser, Context& context)
|
||||
[](const ParametersParser& parser, Context& context, const ShellContext& shell_context)
|
||||
{
|
||||
if (parser.positional_count() == 2)
|
||||
throw wrong_argument_count();
|
||||
|
@ -1513,12 +1518,12 @@ const CommandDesc try_catch_cmd = {
|
|||
CommandManager& command_manager = CommandManager::instance();
|
||||
try
|
||||
{
|
||||
command_manager.execute(parser[0], context);
|
||||
command_manager.execute(parser[0], context, shell_context);
|
||||
}
|
||||
catch (Kakoune::runtime_error& e)
|
||||
{
|
||||
if (do_catch)
|
||||
command_manager.execute(parser[2], context);
|
||||
command_manager.execute(parser[2], context, shell_context);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -1538,13 +1543,13 @@ const CommandDesc face_cmd = {
|
|||
"facespec format is <fg color>[,<bg color>][+<attributes>]\n"
|
||||
"colors are either a color name, or rgb:###### values.\n"
|
||||
"attributes is a combination of:\n"
|
||||
" u: underline, r: reverse, b: bold, B: blink, d: dim\n"
|
||||
" u: underline, r: reverse, b: bold, B: blink, d: dim, e: exclusive\n"
|
||||
"facespec can as well just be the name of another face" ,
|
||||
ParameterDesc{{}, ParameterDesc::Flags::None, 2, 2},
|
||||
CommandFlags::None,
|
||||
CommandHelper{},
|
||||
PerArgumentCommandCompleter({ complete_face, complete_face }),
|
||||
[](const ParametersParser& parser, Context& context)
|
||||
[](const ParametersParser& parser, Context& context, const ShellContext&)
|
||||
{
|
||||
FaceRegistry::instance().register_alias(parser[0], parser[1], true);
|
||||
|
||||
|
@ -1561,7 +1566,7 @@ const CommandDesc set_client_name_cmd = {
|
|||
CommandFlags::None,
|
||||
CommandHelper{},
|
||||
CommandCompleter{},
|
||||
[](const ParametersParser& parser, Context& context)
|
||||
[](const ParametersParser& parser, Context& context, const ShellContext&)
|
||||
{
|
||||
if (ClientManager::instance().validate_client_name(parser[0]))
|
||||
context.set_name(parser[0]);
|
||||
|
@ -1578,7 +1583,7 @@ const CommandDesc set_register_cmd = {
|
|||
CommandFlags::None,
|
||||
CommandHelper{},
|
||||
CommandCompleter{},
|
||||
[](const ParametersParser& parser, Context& context)
|
||||
[](const ParametersParser& parser, Context& context, const ShellContext&)
|
||||
{
|
||||
RegisterManager::instance()[parser[0]] = ConstArrayView<String>(parser[1]);
|
||||
}
|
||||
|
@ -1592,7 +1597,7 @@ const CommandDesc select_cmd = {
|
|||
CommandFlags::None,
|
||||
CommandHelper{},
|
||||
CommandCompleter{},
|
||||
[](const ParametersParser& parser, Context& context)
|
||||
[](const ParametersParser& parser, Context& context, const ShellContext&)
|
||||
{
|
||||
context.selections_write_only() = selection_list_from_string(context.buffer(), parser[0]);
|
||||
}
|
||||
|
@ -1606,7 +1611,7 @@ const CommandDesc change_working_directory_cmd = {
|
|||
CommandFlags::None,
|
||||
CommandHelper{},
|
||||
filename_completer,
|
||||
[](const ParametersParser& parser, Context&)
|
||||
[](const ParametersParser& parser, Context&, const ShellContext&)
|
||||
{
|
||||
if (chdir(parse_filename(parser[0]).c_str()) != 0)
|
||||
throw runtime_error(format("cannot change to directory '{}'", parser[0]));
|
||||
|
@ -1647,7 +1652,7 @@ void exec_keys(ConstArrayView<Key> keys, Context& context)
|
|||
void register_commands()
|
||||
{
|
||||
CommandManager& cm = CommandManager::instance();
|
||||
cm.register_command("nop", [](const ParametersParser&, Context&){}, "do nothing", {});
|
||||
cm.register_command("nop", [](const ParametersParser&, Context&, const ShellContext&){}, "do nothing", {});
|
||||
|
||||
auto register_command = [&](const CommandDesc& c)
|
||||
{
|
||||
|
|
16
src/face.hh
16
src/face.hh
|
@ -10,12 +10,13 @@ namespace Kakoune
|
|||
enum class Attribute : int
|
||||
{
|
||||
Normal = 0,
|
||||
Underline = 1 << 1,
|
||||
Reverse = 1 << 2,
|
||||
Blink = 1 << 3,
|
||||
Bold = 1 << 4,
|
||||
Dim = 1 << 5,
|
||||
Italic = 1 << 6,
|
||||
Exclusive = 1 << 1,
|
||||
Underline = 1 << 2,
|
||||
Reverse = 1 << 3,
|
||||
Blink = 1 << 4,
|
||||
Bold = 1 << 5,
|
||||
Dim = 1 << 6,
|
||||
Italic = 1 << 7,
|
||||
};
|
||||
|
||||
template<> struct WithBitOps<Attribute> : std::true_type {};
|
||||
|
@ -45,7 +46,8 @@ constexpr bool operator!=(const Face& lhs, const Face& rhs)
|
|||
|
||||
constexpr Face merge_faces(const Face& base, const Face& face)
|
||||
{
|
||||
return { face.fg == Color::Default ? base.fg : face.fg,
|
||||
return face.attributes & Attribute::Exclusive ?
|
||||
face : Face{ face.fg == Color::Default ? base.fg : face.fg,
|
||||
face.bg == Color::Default ? base.bg : face.bg,
|
||||
face.attributes | base.attributes };
|
||||
}
|
||||
|
|
|
@ -24,6 +24,7 @@ static Face parse_face(StringView facedesc)
|
|||
{
|
||||
switch (*attr_it)
|
||||
{
|
||||
case 'e': res.attributes |= Attribute::Exclusive; break;
|
||||
case 'u': res.attributes |= Attribute::Underline; break;
|
||||
case 'r': res.attributes |= Attribute::Reverse; break;
|
||||
case 'b': res.attributes |= Attribute::Bold; break;
|
||||
|
|
|
@ -485,7 +485,7 @@ HighlighterAndId create_line_highlighter(HighlighterParameters params)
|
|||
auto func = [=](const Context& context, HighlightFlags flags,
|
||||
DisplayBuffer& display_buffer, BufferRange)
|
||||
{
|
||||
const LineCount line = str_to_int_ifp(expand(option_name, context, {}, EnvVarMap{})).value_or(0) - 1;
|
||||
const LineCount line = str_to_int_ifp(expand(option_name, context)).value_or(0) - 1;
|
||||
if (line < 0)
|
||||
return;
|
||||
|
||||
|
@ -527,7 +527,7 @@ HighlighterAndId create_column_highlighter(HighlighterParameters params)
|
|||
auto func = [=](const Context& context, HighlightFlags flags,
|
||||
DisplayBuffer& display_buffer, BufferRange)
|
||||
{
|
||||
const CharCount column = str_to_int_ifp(expand(option_name, context, {}, EnvVarMap{})).value_or(0) - 1;
|
||||
const CharCount column = str_to_int_ifp(expand(option_name, context)).value_or(0) - 1;
|
||||
if (column < 0)
|
||||
return;
|
||||
|
||||
|
|
|
@ -381,8 +381,7 @@ void pipe(Context& context, NormalParams)
|
|||
in += '\n';
|
||||
auto out = ShellManager::instance().eval(
|
||||
real_cmd, context, in,
|
||||
ShellManager::Flags::WaitForStdout,
|
||||
{}, EnvVarMap{}).first;
|
||||
ShellManager::Flags::WaitForStdout).first;
|
||||
|
||||
if ((insert_eol or sel.max() == buffer.back_coord()) and
|
||||
out.back() == '\n')
|
||||
|
@ -397,8 +396,7 @@ void pipe(Context& context, NormalParams)
|
|||
for (auto& sel : selections)
|
||||
ShellManager::instance().eval(real_cmd, context,
|
||||
content(buffer, sel),
|
||||
ShellManager::Flags::None,
|
||||
{}, EnvVarMap{});
|
||||
ShellManager::Flags::None);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -425,9 +423,8 @@ void insert_output(Context& context, NormalParams)
|
|||
if (real_cmd.empty())
|
||||
return;
|
||||
|
||||
auto str = ShellManager::instance().eval(real_cmd, context, {},
|
||||
ShellManager::Flags::WaitForStdout,
|
||||
{}, EnvVarMap{}).first;
|
||||
auto str = ShellManager::instance().eval(
|
||||
real_cmd, context, {}, ShellManager::Flags::WaitForStdout).first;
|
||||
ScopedEdition edition(context);
|
||||
context.selections().insert(str, mode);
|
||||
});
|
||||
|
@ -781,8 +778,7 @@ void keep_pipe(Context& context, NormalParams)
|
|||
for (auto& sel : context.selections())
|
||||
{
|
||||
if (shell_manager.eval(cmdline, context, content(buffer, sel),
|
||||
ShellManager::Flags::None,
|
||||
{}, EnvVarMap{}).second == 0)
|
||||
ShellManager::Flags::None).second == 0)
|
||||
keep.push_back(sel);
|
||||
}
|
||||
if (keep.empty())
|
||||
|
|
|
@ -16,6 +16,7 @@ namespace Kakoune
|
|||
|
||||
inline String option_to_string(StringView opt) { return opt.str(); }
|
||||
inline void option_from_string(StringView str, String& opt) { opt = str.str(); }
|
||||
inline bool option_add(String& opt, const String& val) { opt += val; return not val.empty(); }
|
||||
|
||||
inline String option_to_string(int opt) { return to_string(opt); }
|
||||
inline void option_from_string(StringView str, int& opt) { opt = str_to_int(str); }
|
||||
|
|
|
@ -83,7 +83,7 @@ pid_t spawn_process(StringView cmdline, ConstArrayView<String> params, ConstArra
|
|||
|
||||
std::pair<String, int> ShellManager::eval(
|
||||
StringView cmdline, const Context& context, StringView input,
|
||||
Flags flags, ConstArrayView<String> params, const EnvVarMap& env_vars)
|
||||
Flags flags, const ShellContext& shell_context)
|
||||
{
|
||||
static const Regex re(R"(\bkak_(\w+)\b)");
|
||||
|
||||
|
@ -100,10 +100,10 @@ std::pair<String, int> ShellManager::eval(
|
|||
if (find_if(kak_env, match_name) != kak_env.end())
|
||||
continue;
|
||||
|
||||
auto var_it = env_vars.find(name);
|
||||
auto var_it = shell_context.env_vars.find(name);
|
||||
try
|
||||
{
|
||||
const String& value = var_it != env_vars.end() ?
|
||||
const String& value = var_it != shell_context.env_vars.end() ?
|
||||
var_it->value : get_val(name, context);
|
||||
|
||||
kak_env.push_back(format("kak_{}={}", name, value));
|
||||
|
@ -111,7 +111,7 @@ std::pair<String, int> ShellManager::eval(
|
|||
}
|
||||
|
||||
Pipe child_stdin, child_stdout, child_stderr;
|
||||
pid_t pid = spawn_process(cmdline, params, kak_env,
|
||||
pid_t pid = spawn_process(cmdline, shell_context.params, kak_env,
|
||||
child_stdin, child_stdout, child_stderr);
|
||||
|
||||
child_stdin.close_read_fd();
|
||||
|
|
|
@ -14,6 +14,12 @@ class Context;
|
|||
|
||||
using EnvVarRetriever = std::function<String (StringView name, const Context&)>;
|
||||
|
||||
struct ShellContext
|
||||
{
|
||||
ConstArrayView<String> params;
|
||||
EnvVarMap env_vars;
|
||||
};
|
||||
|
||||
class ShellManager : public Singleton<ShellManager>
|
||||
{
|
||||
public:
|
||||
|
@ -28,8 +34,7 @@ public:
|
|||
std::pair<String, int> eval(StringView cmdline, const Context& context,
|
||||
StringView input = {},
|
||||
Flags flags = Flags::WaitForStdout,
|
||||
ConstArrayView<String> params = {},
|
||||
const EnvVarMap& env_vars = EnvVarMap{});
|
||||
const ShellContext& shell_context = {});
|
||||
|
||||
void register_env_var(StringView str, bool prefix, EnvVarRetriever retriever);
|
||||
String get_val(StringView name, const Context& context) const;
|
||||
|
|
Loading…
Reference in New Issue
Block a user