Problem when creating grep like command

hi, another noob question
so, this is command to run go build ./… and pipe output to grep buffer.

define-command -docstring %{
    go build ./...
} go-build %{ evaluate-commands %sh{
     output=$(mktemp -d "${TMPDIR:-/tmp}"/kak-go-build.XXXXXXXX)/fifo
     mkfifo ${output}
     ( go build ./... 2>&1 | tr -d '\r' > ${output} 2>&1 & ) > /dev/null 2>&1 < /dev/null

     printf %s\\n "evaluate-commands -try-client '$kak_opt_toolsclient' %{
               edit! -fifo ${output} *build*
               set-option buffer filetype grep
               set-option buffer grep_current_line 0
               hook -always -once buffer BufCloseFifo .* %{
                   try %{
                       exec '<a-K>^$<ret>'
                       echo -markup '{Error}build failed'
                   } catch %{
                       echo 'build ok'
                       db '*build*' 
                   }
                   nop %sh{ rm -r $(dirname ${output}) }
           }}"
}}

basically, it is copypaste from grep.kak with addition of echo command.
point of using echos is that i can switch to another buffer, then have notification about result.
problem: echos not work.
it is because hook works in buffer context and it doesnt have window?

There’s already a make command built in, should just use it

hook global WinSetOption file type=go %{
    set option window makecmd 'go build and whatever else'
}
1 Like

yeah, thx. It is better than copypaste. but why echos not work?

That’s correct, the hook is executed in a draft context without any knowledge of the current client. You can resolve this by doing eval -client '$kak_client' %{ echo "build ok" }, assuming you’re running the go-build command from the current client.

1 Like

ok, this is exactly what i searching for.
but,
why that hook runs in disposable context if -draft switch not specified? i mean that hook have buffer scope too

hook buffer InsertKey .* %{
    echo 'works in buffer scope actually' # expected
}
hook buffer InsertKey .* %{eval %{
    echo 'works too (no -draft swith)' # expected
}}
hook buffer InsertKey .* %{eval -draft %{
    echo 'not work (have -draft swith)' # expected
}}

on what ‘executing in draft context’ depends?

hooks run in different contexts based on what triggers them. InsertKey is tied to a client, so it runs in the client context. The :doc hooks page has some information about this (such as what context some hooks are run in), but not comprehensive.

It’s also not guaranteed what the absence of -draft means. Consider nested eval calls:

eval -draft %{
    eval %{ 
        echo hello
    }
}

Even though the innermost eval is not draft, the echo will not be printed. In this case it’s obvious why, but if you were to put the inner eval into a command, you would not be able to tell what goes wrong just by looking at the command. Similarly, you don’t see the full picture when you just declare a hook.

1 Like

context == scope?
scope can be: window, buffer, global
context can be: ???
by context you mean outer evals?

so,

  1. scope defines where hook work
  2. context defines how it work(tied or not tied to client)

I haven’t found a concise definition of what a context is, but I wrote an introduction to them in another comment a while ago:

1 Like

I think the best way to get an idea about what ‘context’ means is to look at the corresponding class in the source code, in particular the member variables. As you can see, a context is a collection of window / client / buffer / selections, some of which may be empty, which would then cause the behavior to change.

1 Like