-
Notifications
You must be signed in to change notification settings - Fork 702
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Expand the new
/terminal
API
#4425
base: master
Are you sure you want to change the base?
Conversation
If `terminal` is not defined, the editor will say so independently. If it is, more errors might bubble up from the implementation that may be replaced with this (now removed) hardcoded message.
I am not sure this is the right approach, and I think the I think there is a real problem to solve here, there is a class of scripts that do need extra control on how things are split, a diffing script for example wants to be able to do vertical splitting to ensure it does get each pane side by side. Those scripts are relatively rare though, and I dont have a solution for them yet. |
I agree, I don’t like this approach either. You could almost make the argument that the editor doesn’t need to be that aware of multiplexing environments in the first place. I don’t have any ideas, so in the meantime here’s a patch users can compile in to fill the gap. By the way, a good example of a script that could use deterministic client placement from within Kakoune is my Git merge tool, kakmerge! |
Also note that this PR has a bunch of commits that could be considered for merging, independently of the |
Just random ideas and issues I encountered while using Kakoune and its windowing system. I also think the problem is more profound and I don’t have a solution too. Window modeHelix has a window mode on Explicit windowingThere is valid reasons to open a TUI program in Alacritty when in tmux. If we have Client scopeExample: Start Kakoune in Alacritty then open a client in tmux. The windowing detection is done on startup, instead on the client creation, and aliases are global. Window roleExample: fzf See Passing variablesExample how to pass environment variables to a program in the shell:
Currently, we emulate variable passing with a Kakoune command taking another Kakoune command with a certain pattern. define-command -override connect -params 1.. -command-completion -docstring 'Run a command as <command> sh -c {connect} -- [arguments]. Example: connect terminal sh' %{
%arg{1} sh -c %{
export KAKOUNE_SESSION=$1
export KAKOUNE_CLIENT=$2
shift 3
[ $# = 0 ] && set "$SHELL"
"$@"
} -- %val{session} %val{client} %arg{@}
}
define-command -override run -params 1.. -shell-completion -docstring 'Run a program in a new session' %{
nop %sh{
nohup "$@" < /dev/null > /dev/null 2>&1 &
}
} I was hoping for a more convenient way. Occasion for better naming?
|
Could 4433 solve the issue of windowing? What if instead of writing Kakoune commands, we could add shell commands to path? That way a fzf integration for Kakoune would be just: terminal :fzf Note: It was an approach explored in connect.kak. It means the run tmux split-window :attach Or more conveniently if using an alias: split-window :attach |
Is this PR still "valid" in terms of design as of today? |
I still have the same concerns, while having more control over where/how the terminal is created would be great, I do not think this should be done through introducing new commands. Some approach that comes to mind would be to allow alias to refer to other aliases, which would allow:
Then we could possibly have a way to temporarily set an alias for a command (I have been wondering about such a feature for a while, not only for aliases but for various other values such as options as well)
This is still unsatisfying as we need to maintain the terminal, terminal-vertical and terminal-horizontal aliases and can get in weird configuration ( So yeah, I think this needs more design work. |
Just to kick open doors, I have recently spent time discovering and using the Plan 9 Acme editor. And it made me realize how important the proximity between the editor and the windows can be. Opening windows is not an arbitrary action in Acme. Effectively: "The initial placement of a new window is determined automatically". To have more details, here is an extract of the initial paper:
I know Acme and Kakoune are really different, as Acme can almost be seen as a window manager while Kakoune wants to delegate this part. But my point is that I think the editor should be able to control the position, size and content of windows. Simply throwing at the window the command: "create a new window" might not be enough to implement a comfortable multi-file experience. After a few weeks of using Acme, I am amazed at how the editor opens things at the correct location. It is rare that I have to reposition windows by myself. A few simple examples that could be enjoyable in Kakoune if it could better control windows:
I know those examples might be against the Kakoune philosophy, but I just try to defend the other side of the spectrum to demonstrate what it can bring in terms of developer experience. Not all window systems have this possibility, but that would be nice to be able to control at least the position (right/left/up/down) and default for instance to |
All of those sound pretty great, and I do not think they are against Kakoune's philosphy, on the contrary I think Kakoune should enable those use cases, but not in the way you seem to think about it. I think this kind of rules should probably be configured in the windowing system itself, with Kakoune just hinting at what that new window is expected to be used for. I am not sure how to expose a hint that is going to be accessible from the windowing system, maybe env-vars are enough. I tend not to have too many issues with window management in my day to day workflow because I usually create 3/4 clients at startup (using the |
This seems interesting even if I am not sure how to effectively grasp the idea. I'd be glad to have more details about your thinking here.
This works for some workflows, yes, and it is already great that Kakoune supports this. However, I think it works best for "static" layouts, where you know where things should be located in advance. In Acme, the size of the window is optimized. So let's say I create an empty buffer in the right column, and then I decide to type "ls -l" and bash-execute this command with mouse button 2 (yes Acme is mouse oriented and mouse 2 "executes" what is being selected). It will create another window for the result, and it will take pretty much the whole height, as my buffer containing "ls -l" is small enough and only contains that line. So it optimizes space. Then, you also have a notion of "last edited" column. If I execute a grep command from within the same buffer of my "ls -l", the output is shown in the right column below on the same column ( From there, I can review my search. I see there are matches in the same file opened on the left column ( But if I intend to modify this match in Again, those are just examples. With this system, Acme allows a lot of different dynamic workflows for users. And I find them handy. I show Acme here, and by no means do I say that Kakoune should resemble Acme in that regard, nor that it needs such a sophisticated system. But it is more to provide ideas so that inspiration could be taken from tools that do it in an interesting way. Before I was mostly using a single window to work, but I started to realize that multiwindow workflows are also great. |
This is a slightly different approach than mawww#4425. It allows to create mappings that work in either windowing system like map global user c %{:with-option windowing_placement window new<ret>} map global user '"' %{:with-option windowing_placement vertical new<ret>} map global user '%' %{:with-option windowing_placement horizontal new<ret>} Or, when using multiple windowing systems concurrently, you might want to add mappings like map global user t %{:with-option windowing_module tmux new<ret>} map global user T %{:with-option windowing_module wayland new<ret>} TODO: maybe add a reasonable measure of backwards compatibility. We could try to keep the alias approach and implement a "with-alias" command, however that is not powerful enough to capture the two dimensions (windowing system and placement).
…t in new/terminal commands Today I can control "terminal" and "new" by changing the terminal alias but I always need to choose a concrete implementation, like "tmux-terminal-horizontal", even when there is otherwise no need to mention tmux in my config. Allow to configure these by introducing new options for the windowing system and window placement. This allows to create mappings that work in either windowing system like map global user c %{:with-option windowing_placement window new<ret>} map global user '"' %{:with-option windowing_placement vertical new<ret>} map global user '%' %{:with-option windowing_placement horizontal new<ret>} Or, when using multiple windowing systems concurrently, you might want to add mappings like map global user t %{:with-option windowing_module tmux new<ret>} map global user T %{:with-option windowing_module wayland new<ret>} TODO: maybe add a reasonable measure of backwards compatibility. We could try to keep the alias approach and implement a "with-alias" command, however that approach can only capture both dimensions (windowing system and placement) if we add tons of commands like "terminal-horizontal" (with implied windowing system) and "tmux-terminal" (with implied placement). Closes mawww#3943, mawww#4425
…t in new/terminal commands Today I can control "terminal" and "new" by changing the terminal alias but I always need to choose a concrete implementation, like "tmux-terminal-horizontal", even when there is otherwise no need to mention tmux in my config. Allow to configure windowing system and window placement separately by introducing dedicated options. This allows to create mappings that work in any windowing system like map global user c %{:with-option windowing_placement window new<ret>} map global user '"' %{:with-option windowing_placement vertical new<ret>} map global user '%' %{:with-option windowing_placement horizontal new<ret>} For windowing systems that don't support all placements, you can wrap the above in try/catch, falling back on the "window" variant which is defined for all windowing systems. When using multiple windowing systems concurrently, you might want to add mappings like map global user t %{:with-option windowing_module tmux new<ret>} map global user T %{:with-option windowing_module wayland new<ret>} --- This changes the default `terminal` alias for some modules. In particular, instead of delegating to iterm-terminal-vertical screen-terminal-vertical tmux-terminal-horizontal wezterm-terminal-vertical it will now by default delegate to the respective `-window` variant. Also, this removes the "terminal-tab" alias which was only defined by the kitty module. We could try to keep the alias approach and implement a "with-alias" command, however that approach can only capture both dimensions (windowing system and placement) if we add tons of commands like "terminal-horizontal" (with implied windowing system) and "tmux-terminal" (with implied placement). Side thought: we could also get rid of the `focus` alias and instead define define-command focus %{ "%opt{windowing_module}-focus" } Closes mawww#3943, mawww#4425
here's a slightly different approach to the same end at #5020 |
…t in new/terminal commands Today I can control "terminal" and "new" by changing the terminal alias but I always need to choose a concrete implementation, like "tmux-terminal-horizontal", even when there is otherwise no need to mention tmux in my config. Allow to configure windowing system and window placement independently by introducing dedicated options. This allows to create mappings that work in any windowing system like map global user c %{:with-option windowing_placement window new<ret>} map global user '"' %{:with-option windowing_placement vertical new<ret>} map global user '%' %{:with-option windowing_placement horizontal new<ret>} For windowing systems that don't support all placements, you can wrap the above in try/catch to fall back on the "window" variant which is defined for all windowing systems. When using multiple (nested) windowing systems, you might want to add mappings like map global user t %{:with-option windowing_module tmux new<ret>} map global user T %{:with-option windowing_module wayland new<ret>} --- This changes the default "terminal" alias for some modules. In particular, instead of delegating to iterm-terminal-vertical screen-terminal-vertical tmux-terminal-horizontal wezterm-terminal-vertical it will now by default delegate to the respective "-window" variant. We could maintain backwards compatiblity here by setting the "windowing_placement" option accordingly, but the new behavior seems more logical? Also, this removes the "terminal-tab" alias which was only defined by the kitty module. We could try to keep the alias approach and implement a "with-alias" command, however that approach can only capture both dimensions (windowing system and placement) if we add tons of commands like "terminal-horizontal" (with implied windowing system) and "tmux-terminal" (with implied placement). Side thought: we could also get rid of the "focus" alias and instead define define-command focus %{ "%opt{windowing_module}-focus" } Closes mawww#3943, mawww#4425
…t in new/terminal commands Today I can control "terminal" and "new" by changing the terminal alias but I always need to choose a concrete implementation, like "tmux-terminal-horizontal", even when there is otherwise no need to mention tmux in my config. Allow to configure windowing system and window placement independently by introducing dedicated options. This allows to create mappings that work in any windowing system like map global user c %{:with-option windowing_placement window new<ret>} map global user '"' %{:with-option windowing_placement vertical new<ret>} map global user '%' %{:with-option windowing_placement horizontal new<ret>} For windowing systems that don't support all placements, you can wrap the above in try/catch to fall back on the "window" variant which is defined for all windowing systems. When using multiple (nested) windowing systems, you might want to add mappings like map global user t %{:with-option windowing_module tmux new<ret>} map global user T %{:with-option windowing_module wayland new<ret>} --- This changes the default "terminal" alias for some modules. In particular, instead of delegating to iterm-terminal-vertical screen-terminal-vertical tmux-terminal-horizontal wezterm-terminal-vertical it will now by default delegate to the respective "-window" variant. We could maintain backwards compatiblity here by setting the "windowing_placement" option accordingly, but the new behavior seems more logical? Also, this removes the "terminal-tab" alias which was only defined by the kitty module. We could try to keep the alias approach and implement a "with-alias" command, however that approach can only capture both dimensions (windowing system and placement) if we add tons of commands like "terminal-horizontal" (with implied windowing system) and "tmux-terminal" (with implied placement). Side thought: we could also get rid of the "focus" alias and instead define define-command focus %{ "%opt{windowing_module}-focus" } Closes mawww#3943, mawww#4425
This PR allows users to control more accurately where new Kakoune clients are spawned via the
:new
API:vertical
horizontal
,window
.The
terminal
API had to be extended similarly as a consequence. I also noticed that aterminal-tab
alias was sneaked intokitty.kak
, so that’s supported as well, since tabs are a common type of window nowadays. Not all our multiplexer support scripts implement it though.The other commits are consistency fixes or cosmetics.
Fixes #3943.