helix
helix copied to clipboard
Simple :sh command substitutions
It would be nice to be able to reference editor information on the :sh
line.
Things like for example:
subs | description |
---|---|
$fn | filename (= $bn.$ex) |
$bn | basename |
$ex | extension |
$fp | full path |
$rp | relative path (to .git root?) |
$ln | line number |
to be able to execute things like:
:sh gh browse $fn:$ln
Of course above example is just a starting point to get the idea across.
It's a bit of a nit but I'd prefer more explicit names like $file
, $line
rather than two-character shortcuts. They're not very discoverable and are only marginally easier to type
Indeed, whole words as tokens is indeed nicer, especially when combined with completion to speed up the typing.
Also it occurred to me the $
prefix may not be such a great idea, as it commonly used by sh
itself. What about #
as a tokenizer?
-
#line
-
#filename
Etc. (TBD)
I imagine this would be implemented by setting environment variables for the shell command and then the shell command would interpret them - so $var
for unix-like and %var%
or whatever it is for windows - rather than a search-and-replace or templating language rendered ahead of time.
Ah, yes, of course we have full control over the env space at execution time.
Still would like to have some help typing the longer vars though ;)
I think longer variable names also follows Helix' way of doing things. I imagine that aliases would be implemented in the future with more configuration options.
Instead of environment variables, configuration variables could be used as well, for the project/.helix
directory.
Revised table:
env | description |
---|---|
$HX_FILENAME | filename |
~~$HX_BASENAME~~ | basename |
~~$HX_FILE_EXT~~ | file extension |
$HX_PATH | full absolute path |
~~$HX_RELATIVE_PATH~~ | relative path (to .git root? or $CWD) |
$HX_LINE | line number |
$HX_COLUMN | cursor pos (on line) |
I think we should start small: we probably only need file, line and column. The others can be derived in the shell with basename
/extname
/dirname
/pwd
/etc (I'm sure windows has equivalents, right? 🙃)
I would suggest keeping $HX_PATH as this is a known fact of the editor, not having it would add unneeded clutter to constructing an arbitrary command line.
... (I'm sure windows has equivalents, right? 🙃)
🕵️♂️ No clue either, haven't used it in a long time.. but I certainly hope command.com got improved upon. 🤔 Is Cygwin still around?
Windows has the capacity to derive the same values and Cygwin, or similar programs, are available. I'd recommend WSL if you need Linux capabilities, though, compared to Cygwin or other alternatives.
I kind of like the way Kakoune does it. They have interpolations like %val{bufname}
(access a value) or %opt{filetype}
(access an option), but some common things are also in registers, which Helix already supports, but they just have more of them. The %
register contains the buffer name, so you can always <C-r> %
to get the buffer name.
On that note I'd love to be able to access the regex captures that way too - registers 0-9 in Kakoune are used for the capture groups. So you can s pattern <ret> c <C-r> 1 <esc>
to replace with capture group 1 for example.
@devyn Ah, that's an interesting take on it. Looks pretty nice. I wonder if there's a common Rust library that essentially does the same thing.
Kakoune Commands (Prompt) Kakoune Prompt Expansion
The only expansions I can think of with Vim is %
and #
, but I'm really not a fan of how unintuitive it feels. I'm sure there are other things that I'm simply not aware of, given the docs and implementation.
The percent register comes from vim. I have a habit of constantly in vim using adhoc shell commands like eg. !git diff %
. (diff of the current file), !ls %:s/src/
(list of a subdirectory of the current file's location). And I'm kind of missing it.
Bonus points for keeping it simple to type.
it would be great to define custom variables like these as part of my config as well - I'm currently using kitty remote to trigger tests, file browser, etc. however, every command I build has to begin with 40 characters of setup before I get to my 6 character's command and sh
apparently doesn't get access to my shell's aliases so I can't make these shorter outside helix as well...
e.g.
[keys.normal]
C-f = ":sh kitty @ launch --no-response --copy-env --hold --cwd=current --type=overlay lf"
C-t = ":sh kitty @ launch --no-response --copy-env --hold --cwd=current --type=tab mix test"
C-T = ":sh kitty @ launch --no-response --copy-env --hold --cwd=current --type=tab pnpm test"
vs
[keys.normal]
C-f = ":sh $HX_OVERLAY lf"
C-t = ":sh $HX_TAB mix test"
C-T = ":sh $HX_TAB pnpm test"
[shell]
OVERLAY = "kitty @ launch --no-response --copy-env --hold --cwd=current --type=overlay"
TAB = "kitty @ launch --no-response --copy-env --hold --cwd=current --type=tab"
It could potentially be useful to also provide context information like the class / function path names relative to the current cursor position e.g. to trigger single tests for some test runners. See also https://github.com/helix-editor/helix/discussions/5014#discussioncomment-4346933.
I would love something like this to be able to make a copy of the current file I am working on in the same directory. e.g.
Given I have a/b/one.txt
opened, I will like to create a/b/two.txt
with something like
:w $pwd/two.txt
to be able to execute things like:
:sh gh browse $fn:$ln
This is the exact use case I came here looking for. It would be nice to support a multiline selection (like GBrowse
from vim-fugitive). Would it be reasonable to add $HX_LINE_END
and $HX_COLUMN_END
?
I'm assuming that the LINE/COLUMN vars refer only to the primary selection, and other cursors are ignored, right? Or do we run the command separately on each selection?
Not being able to have commands parameterized by either context variables like the current file or the output of a shell command is blocking so many workflow integration tasks for me (stuff like keys.normal."\\".j = ":o ~/journal/%sh{my-date-alias}.md"
using the syntax of #3393), but I don't have Rust chops (yet) and haven't wanted to be a "me too" clogging that PR's thread.
I think simple and well-designed shell-integration features like this, the existing shell_*
family of commands, and a good implementation of job-control-based tag-teaming with other apps like ranger, as laid out in kakoune/wiki: Integrating Other CLI Apps (I'll probably do this and document it soon, if someone else doesn't) can take care of a large portion of the use cases a lot of folks are thinking of when they go looking for a "Plugin system", leaving the real eventual plugins API (#3806) the remaining usecases that require substantial, nontrivial, and deep integration with Helix. Thanks for listening to my TED talk.
This is a really important feature for using helix. Apparently https://github.com/helix-editor/helix/pull/6979 got stuck. I hope it'd be merged soon.
Is there a way to copy %
(document path) to *
(system path) for a temporary solution? Thanks!
This one is the only issue that is keeping me from switching to helix. The thing is that helix has great built in features however there are few things which are non standard that I heavily rely on. Unfortunately helix is not giving us any way to integrate custom stuff. Adding a way to pass information about current selection (or current cursor positions) to a shell script would solve 90% of the issues.