1
1
mirror of https://github.com/mawww/kakoune.git synced 2024-07-14 16:10:24 +03:00

Compare commits

...

15 Commits

Author SHA1 Message Date
Max Schillinger
4b04f666f7
Merge 1bd5637b56 into e0bbd1e7ca 2024-07-01 20:46:03 +02:00
Maxime Coste
e0bbd1e7ca Merge remote-tracking branch 'PJungkamp/directory-changed' 2024-07-01 21:31:17 +10:00
Daniel Gorin
8ca7b5815a erlang: Fix the comment_line configuration
Erlang comments start with `%`. This is correctly highlighted
but the comment-line/comment-block commands don't work correctly.
2024-06-27 13:10:21 +01:00
Maxime Coste
80fcfebca8 Fix order of evaluation issue when compiling regex alternations
The previous implementation was relying on the left hand side of the
assignement's side effects to be sequenced before the right hand side
evaluation (so --split_pos was expected to have taken place)

This is actually counter to C++17 which guarantees evaluation of the
right hand side of the assignement first. For some reason this is
not the case with GCC on linux.
2024-06-26 22:38:01 +10:00
Maxime Coste
cbdd200e73 Fix corner case in passin arguments to grep and make 2024-06-26 20:35:34 +10:00
Philipp Jungkamp
0a10612786 Add EnterDirectory hook
This hook runs on `change-directory` and is also emitted just before
KakBegin after kakrc has been sourced.
2024-06-24 16:16:33 +02:00
Philipp Jungkamp
07000adb9b Philipp Jungkamp Copyright Waiver
I dedicate any and all copyright interest in this software to the
public domain.  I make this dedication for the benefit of the public at
large and to the detriment of my heirs and successors.  I intend this
dedication to be an overt act of relinquishment in perpetuity of all
present and future rights to this software under copyright law.
2024-06-24 16:16:33 +02:00
Maxime Coste
374a7a8c99 Remove some selection copies in pipe and throw early if read only
Throwing early avoids losing selections in this case.
2024-06-24 21:18:17 +10:00
Maxime Coste
6674fe7587 Merge remote-tracking branch 'stacyharper/elixir-heex' 2024-06-23 11:14:34 +10:00
Maxime Coste
4a00a6edea Fix trailing whitespaces 2024-06-23 11:03:50 +10:00
Tobias Pisani
6493ddad42 Allow individual show-whitespace options to be turned off
This is especially useful to use the indent guides without the  other
parameters, but in general it can be a useful option.

It could be worth considering cleaning up these options to default off instead, but
the default also seems useful, so i consider this ok, as it might be the more advanced
usecase.
2024-06-23 11:03:03 +10:00
Maxime Coste
880ad98a30 Add a -script switch to the fifo to cater for grep/make use cases
Avoid the brittle `exit; %arg{@}` trick
2024-06-22 17:02:54 +10:00
Willow Barraco
0bb355557e
elixir: detect heex additionaly to leex 2024-06-19 12:45:20 +02:00
Max Schillinger
1bd5637b56 Update tutorial: How to end a macro 2024-03-13 15:44:30 +01:00
Max Schillinger
eb5db3f0fd Maximilian Schillinger Copyright Waiver
I dedicate any and all copyright interest in this software to the
public domain.  I make this dedication for the benefit of the public at
large and to the detriment of my heirs and successors.  I intend this
dedication to be an overt act of relinquishment in perpetuity of all
present and future rights to this software under copyright law.
2024-03-13 15:39:04 +01:00
22 changed files with 82 additions and 56 deletions

View File

@ -455,8 +455,8 @@ using the built-in `:doc` command.
| Q | chunk interactively, and replay the sequence of keys
`---' at will. The sequence in question is a macro: the `Q`
primitive will create a new one (i.e., record all the keys
.---, .---, hit henceforth until the escape key `<esc>` is hit), and
|ctl|+| r |_. the `q` primitive will replay the keys saved in the macro.
.---, .---, hit henceforth until `Q` is hit again), and the `q`
|ctl|+| r |_. primitive will replay the keys saved in the macro.
`---' `---' `.---,
| @ | Notes: macros can easily be translated into a proper
`---' script, as they are saved in the `@` register, which you

View File

@ -41,22 +41,27 @@ highlighter is replaced with the new one.
using the `Whitespace` face, with the following *options*:
*-lf* <separator>:::
a one character long separator that will replace line feeds
a one character long separator that will replace line feeds,
or an empty string to ignore them.
*-spc* <separator>:::
a one character long separator that will replace spaces
a one character long separator that will replace spaces,
or an empty string to ignore them.
*-nbsp* <separator>:::
a one character long separator that will replace non-breakable spaces
a one character long separator that will replace non-breakable spaces,
or an empty string to ignore them.
*-tab* <separator>:::
a one character long separator that will replace tabulations
a one character long separator that will replace tabulations,
or an empty string to ignore them.
*-tabpad* <separator>:::
a one character long separator that will be appended to tabulations to honor the *tabstop* option
*-indent* <separator>:::
a one character long separator that will replace the first space in indentation according to the *indentwidth* option
a one character long separator that will replace the first space in indentation
according to the *indentwidth* option, or an empty string to ignore them.
This will use the `WhitespaceIndent` face.
*-only-trailing*:::

View File

@ -147,6 +147,11 @@ name. Hooks with no description will always use an empty string.
*SessionRenamed* `<old name>:<new name>`::
executed when a session is renamed using the `rename-session` command
*EnterDirectory* `path`::
executed on startup and when the current working directory is changed
using the `change-directory` command. The hook param is an absolute path
to the new working directory.
*RuntimeError* `error message`::
an error was encountered while executing a user command

View File

@ -8,7 +8,7 @@ hook global BufCreate .*[.](ex|exs) %{
set-option buffer filetype elixir
}
hook global BufCreate .*[.]html[.]l?eex %{
hook global BufCreate .*[.]html[.][lh]?eex %{
set-option buffer filetype eex
}
@ -64,6 +64,7 @@ add-highlighter shared/elixir/single_string region "'" "(?<!\\)(?:\\\\)*'" fill
add-highlighter shared/elixir/comment region '#' '$' fill comment
add-highlighter shared/elixir/leex region -match-capture '~L("""|")' '(?<!\\)(?:\\\\)*("""|")' ref eex
add-highlighter shared/elixir/heex region -match-capture '~H("""|")' '(?<!\\)(?:\\\\)*("""|")' ref eex
add-highlighter shared/elixir/double_string/base default-region fill string
add-highlighter shared/elixir/double_string/interpolation region -recurse \{ \Q#{ \} fill builtin

View File

@ -75,7 +75,7 @@ hook global BufSetOption filetype=(html|xml) %{
set-option buffer comment_block_end '-->'
}
hook global BufSetOption filetype=(latex|mercury) %{
hook global BufSetOption filetype=(erlang|latex|mercury) %{
set-option buffer comment_line '%'
}

View File

@ -1,12 +1,14 @@
provide-module fifo %{
define-command -params .. -docstring %{
fifo [-name <buffer-name>] [-scroll] [--] <command>...: run command in a fifo buffer
fifo [-name <name>] [-scroll] [-script <script>] [--] <args>...: run command in a fifo buffer
if <script> is used, eval it with <args> as '$@', else pass arguments directly to the shell
} fifo %{ evaluate-commands %sh{
name='*fifo*'
while true; do
case "$1" in
"-scroll") scroll="-scroll"; shift ;;
"-script") script="$2"; shift 2 ;;
"-name") name="$2"; shift 2 ;;
"--") shift; break ;;
*) break ;;
@ -14,7 +16,11 @@ define-command -params .. -docstring %{
done
output=$(mktemp -d "${TMPDIR:-/tmp}"/kak-fifo.XXXXXXXX)/fifo
mkfifo ${output}
( eval "$@" > ${output} 2>&1 & ) > /dev/null 2>&1 < /dev/null
if [ -n "$script" ]; then
( eval "$script" > ${output} 2>&1 & ) > /dev/null 2>&1 < /dev/null
else
( "$@" > ${output} 2>&1 & ) > /dev/null 2>&1 < /dev/null
fi
printf %s\\n "
edit! -fifo ${output} ${scroll} ${name}

View File

@ -12,8 +12,7 @@ define-command -params .. -docstring %{
Passing no argument will perform a literal-string grep for the current selection
} grep %{
evaluate-commands -try-client %opt{toolsclient} %{
fifo -name *grep* %{
shift 2
fifo -name *grep* -script %{
trap - INT QUIT
if [ $# -eq 0 ]; then
case "$kak_opt_grepcmd" in
@ -29,7 +28,7 @@ define-command -params .. -docstring %{
esac
fi
$kak_opt_grepcmd "$@" 2>&1 | tr -d '\r'
} 'exit;' %arg{@} # pass arguments for "$@" above, exit to avoid evaluating them
} -- %arg{@}
set-option buffer filetype grep
set-option buffer jump_current_line 0
}

View File

@ -13,11 +13,10 @@ define-command -params .. -docstring %{
All the optional arguments are forwarded to the make utility
} make %{
evaluate-commands -try-client %opt{toolsclient} %{
fifo -scroll -name *make* %{
shift 2
fifo -scroll -name *make* -script %{
trap - INT QUIT
$kak_opt_makecmd "$@"
} 'exit;' %arg{@} # pass arguments for "$@" above, exit to avoid evaluating them
} -- %arg{@}
set-option buffer filetype make
set-option buffer jump_current_line 0
}

View File

@ -2600,13 +2600,15 @@ const CommandDesc change_directory_cmd = {
cursor_pos, FilenameFlags::OnlyDirectories),
Completions::Flags::Menu };
}),
[](const ParametersParser& parser, Context&, const ShellContext&)
[](const ParametersParser& parser, Context& ctx, const ShellContext&)
{
StringView target = parser.positional_count() == 1 ? StringView{parser[0]} : "~";
if (chdir(parse_filename(target).c_str()) != 0)
auto path = real_path(parse_filename(target));
if (chdir(path.c_str()) != 0)
throw runtime_error(format("unable to change to directory: '{}'", target));
for (auto& buffer : BufferManager::instance())
buffer->update_display_name();
ctx.hooks().run_hook(Hook::EnterDirectory, path, ctx);
}
};

View File

@ -424,7 +424,7 @@ StringView Context::main_sel_register_value(StringView reg) const
return RegisterManager::instance()[reg].get_main(*this, index);
}
void Context::set_name(String name) {
void Context::set_name(String name) {
String old_name = std::exchange(m_name, std::move(name));
hooks().run_hook(Hook::ClientRenamed, format("{}:{}", old_name, m_name), *this);
}

View File

@ -239,7 +239,7 @@ struct HashMap
constexpr bool contains(const KeyType& key) const { return find_index(key) >= 0; }
template<typename KeyType> requires IsHashCompatible<Key, std::remove_cvref_t<KeyType>>
constexpr EffectiveValue& operator[](KeyType&& key)
constexpr EffectiveValue& operator[](KeyType&& key)
{
const auto hash = hash_value(key);
auto index = find_index(key, hash);

View File

@ -981,18 +981,14 @@ struct ShowWhitespacesHighlighter : Highlighter
bool only_trailing = (bool) parser.get_switch("only-trailing");
auto get_param = [&](StringView param, StringView fallback) {
StringView value = parser.get_switch(param).value_or(fallback);
if (value.char_length() != 1)
throw runtime_error{format("-{} expects a single character parameter", param)};
if (value.char_length() > 1)
throw runtime_error{format("-{} expects a single character or empty parameter", param)};
return value.str();
};
String indent = parser.get_switch("indent").value_or("").str();
if (indent.char_length() > 1)
throw runtime_error{format("-indent expects a single character or empty parameter")};
return std::make_unique<ShowWhitespacesHighlighter>(
get_param("tab", ""), get_param("tabpad", " "), get_param("spc", "·"),
get_param("lf", "¬"), get_param("nbsp", ""), indent, only_trailing);
get_param("lf", "¬"), get_param("nbsp", ""), get_param("indent", ""), only_trailing);
}
private:
@ -1043,28 +1039,28 @@ private:
if (it != end)
atom_it = line.split(atom_it, it.coord());
if (cp == '\t')
if (cp == '\t' and not m_tab.empty() and not m_tabpad.empty())
{
const ColumnCount column = get_column(buffer, tabstop, coord);
const ColumnCount count = tabstop - (column % tabstop);
atom_it->replace(m_tab + String(m_tabpad[(CharCount)0], count - m_tab.column_length()));
}
else if (cp == ' ') {
if (m_indent.empty() or indentwidth == 0 or not is_indentation) {
else if (cp == ' ' and is_indentation and indentwidth > 0 and not m_indent.empty()) {
const ColumnCount column = get_column(buffer, tabstop, coord);
if (column % indentwidth == 0 and column != 0) {
atom_it->replace(m_indent);
face = indentface;
}
else {
atom_it->replace(m_spc);
} else {
const ColumnCount column = get_column(buffer, tabstop, coord);
if (column % indentwidth == 0 and column != 0) {
atom_it->replace(m_indent);
face = indentface;
} else {
atom_it->replace(m_spc);
}
}
}
else if (cp == '\n')
else if (cp == ' ' and not m_spc.empty()) {
atom_it->replace(m_spc);
}
else if (cp == '\n' and not m_lf.empty())
atom_it->replace(m_lf);
else if (cp == 0xA0 or cp == 0x202F)
else if ((cp == 0xA0 or cp == 0x202F) and not m_nbsp.empty())
atom_it->replace(m_nbsp);
atom_it->face = merge_faces(atom_it->face, face);
break;

View File

@ -50,6 +50,7 @@ enum class Hook
NextKeyIdle,
NormalKey,
ModeChange,
EnterDirectory,
RawKey,
RegisterModified,
WinClose,
@ -97,6 +98,7 @@ constexpr auto enum_desc(Meta::Type<Hook>)
{Hook::NextKeyIdle, "NextKeyIdle"},
{Hook::NormalKey, "NormalKey"},
{Hook::ModeChange, "ModeChange"},
{Hook::EnterDirectory, "EnterDirectory"},
{Hook::RawKey, "RawKey"},
{Hook::RegisterModified, "RegisterModified"},
{Hook::WinClose, "WinClose"},

View File

@ -842,6 +842,7 @@ int run_server(StringView session, StringView server_init,
{
Context empty_context{Context::EmptyContextFlag{}};
global_scope.hooks().run_hook(Hook::EnterDirectory, real_path("."), empty_context);
global_scope.hooks().run_hook(Hook::KakBegin, session, empty_context);
}

View File

@ -589,13 +589,13 @@ void pipe(Context& context, NormalParams params)
return;
Buffer& buffer = context.buffer();
SelectionList selections = context.selections();
if (replace)
{
buffer.throw_if_read_only();
ScopedEdition edition(context);
ForwardChangesTracker changes_tracker;
size_t timestamp = buffer.timestamp();
Vector<Selection> new_sels;
SelectionList selections = context.selections();
for (auto& sel : selections)
{
const auto beg = changes_tracker.get_new_coord_tolerant(sel.min());
@ -614,20 +614,27 @@ void pipe(Context& context, NormalParams params)
auto new_end = apply_diff(buffer, beg, in, out);
if (new_end != beg)
new_sels.push_back(keep_direction({beg, buffer.char_prev(new_end), std::move(sel.captures())}, sel));
{
auto& min = sel.min();
auto& max = sel.max();
min = beg;
max = buffer.char_prev(new_end);
}
else
{
if (new_end != BufferCoord{})
new_end = buffer.char_prev(new_end);
new_sels.push_back({new_end, new_end, std::move(sel.captures())});
sel.set(new_end);
}
changes_tracker.update(buffer, timestamp);
}
context.selections_write_only().set(std::move(new_sels), selections.main_index());
selections.force_timestamp(timestamp);
context.selections_write_only() = std::move(selections);
}
else
{
SelectionList& selections = context.selections();
const auto old_main = selections.main_index();
for (int i = 0; i < selections.size(); ++i)
{

View File

@ -753,7 +753,10 @@ private:
{
auto node = compile_node<direction>(child);
if (child != index+1)
m_program.instructions[--split_pos].param.split = CompiledRegex::Param::Split{.offset = offset(node, split_pos), .prioritize_parent = true};
{
--split_pos;
m_program.instructions[split_pos].param.split = {.offset = offset(node, split_pos), .prioritize_parent = true};
}
if (get_node(child).children_end != end)
{
auto jump = push_inst(CompiledRegex::Jump);

View File

@ -40,7 +40,7 @@ void HistoryRegister::set(Context& context, ConstArrayView<String> values, bool
return;
}
for (auto&& entry : values | reverse())
for (auto&& entry : values | reverse())
{
m_content.erase(std::remove(m_content.begin(), m_content.end(), entry), m_content.end());
m_content.insert(m_content.begin(), entry);

View File

@ -6,7 +6,7 @@
namespace Kakoune
{
namespace
namespace
{
// Avoid including all of <algorithm> just for this.
constexpr auto max(auto lhs, auto rhs) { return lhs > rhs ? lhs : rhs;}
@ -69,7 +69,7 @@ void String::Data::reserve(size_t new_capacity)
if (current_capacity != 0 and new_capacity <= current_capacity)
return;
if (!is_long() and new_capacity <= Short::capacity)
if (!is_long() and new_capacity <= Short::capacity)
return;
kak_assert(new_capacity <= Long::max_capacity);

View File

@ -169,9 +169,9 @@ public:
using Alloc = Allocator<char, MemoryDomain::String>;
Data() { set_empty(); }
Data(NoCopy, const char* data, size_t size) : u{Long{const_cast<char*>(data),
Data(NoCopy, const char* data, size_t size) : u{Long{const_cast<char*>(data),
size,
/*capacity=*/0,
/*capacity=*/0,
/*mode=*/Long::active_mask}} {}
Data(const char* data, size_t size, size_t capacity);

View File

@ -202,7 +202,7 @@ InplaceString<23> to_string(Grouped val)
InplaceString<23> res;
for (int pos = 0, len = ungrouped.m_length; pos != len; ++pos)
{
if (res.m_length and ((len - pos) % 3) == 0)
if (res.m_length and ((len - pos) % 3) == 0)
res.m_data[res.m_length++] = ',';
res.m_data[res.m_length++] = ungrouped.m_data[pos];
}

View File

@ -144,10 +144,10 @@ decltype(auto) to_string(const StronglyTypedNumber<RealType, ValueType>& val)
namespace detail
{
template<typename T> requires std::is_convertible_v<T, StringView>
template<typename T> requires std::is_convertible_v<T, StringView>
StringView format_param(const T& val) { return val; }
template<typename T> requires (not std::is_convertible_v<T, StringView>)
template<typename T> requires (not std::is_convertible_v<T, StringView>)
decltype(auto) format_param(const T& val) { return to_string(val); }
}

View File

@ -377,7 +377,7 @@ void TerminalUI::Screen::output(bool force, bool synchronized, Writer& writer)
{
for (int line = 0; line < (int)size.line; ++line)
{
auto hash = hash_line(lines[line]);
auto hash = hash_line(lines[line]);
if (hash == hashes[line])
continue;
hashes[line] = hash;