Obsidian-Code-Styler
Obsidian-Code-Styler copied to clipboard
Feature Request: Terminal Appearance
Summary
Add a terminal parameter and terminal codebloc processor.
The terminal parameter should make the codeblock appear as if it were a terminal
The terminal codeblock should allow for indicating what the command was and what the output was and otherwise render it as a shellscript codeblock
For the terminal codeblock you should be able to:
- Choose the output character i.e.
$or>etc. - Set user, directory, device etc.
- Make runnable using execute code plugin
- Make
terminalcodeblock useterminalparameter appearance
Basic example
```terminal
> command_1\
command_2
output_1
output_2
output_3
```
and
```bash terminal
bash script
```
These should both be styled as terminals.
Motivation
Nice styling for terminal code.
Existing Requests?
No existing requests.
I'd happily give this a shot, but want to make sure I do it right.
Where would this be implemented? From what I see in the source, it looks like I could modify SyntaxHighlighting.ts to add a 'terminal' mode.
Hmmm, I was actually thinking of adding it as a custom codeblock so that things could be set like directory, username etc. that are shown at the start of each line. Also for cd commands, I'd want these to show up in the terminal as well which would require more parsing than can be done when marking up a codeblock. In that case, I would implement it as one or two files similar to Referencing.ts and maybe ReferenceParsing.ts (i.e. Terminal.ts and maybe TerminalParsing.ts). The syntax highlighting file is just for adding modes to already styled code blocks so I would additionally add the shell mode to syntax highlight the terminal codeblock.
If you want to just implement it as a an appearance thing with no additional things as I was originally going to do, this would need to be done in a much more complicated way since it would involve adding something like terminal as a codeblock parameter, then when decorating the codeblocks, check if the decorating parameter is present and modify the line number elements to actually show some other terminal info like path etc. This would require extensive css changes I think.
I'd personally want it to be done as a codeblock so you get appearance features like prompts the line above the results, also specifying the output of things like ls should be doable to replicate actual terminals as much as possible.
So I would want to implement it as:
```terminal
> cd
> ls
file 1.md
file 2.txt
> brew list | grep basictex
basictex
```
Where basic things like cd can be parsed to change the pathname without any needed changes and more complicated things need their output specified.
I also want the prompt to (optionally) appear on the line above (as shown below) with the output the next line.
Additionally, I'd want to be able to set the prompt format and things like username, time, starting directory etc. hence why I think a codeblock is better. If you would still like to start on it, I'd recommend creating a new file Terminal.ts and starting with commands for parsing blocks of the above format, then create the elements that show the relevant content and finally make it display nicely with css. Sorry for the extremely long-winded post, I've been putting off doing this since it's a bit more complicated to do it well than I'd like but I want to make sure its done properly!
On the contrary, I'm grateful for the detailed response.
I'm with you for all the features you mentioned and precisely what I'm after too.
One thing I'm less clear about is the two different possibilities you mention. The first is to implement it with a custom codeblock, as opposed to implementing it as a codeblock parameter. Could you explain the difference or point me to a file which demonstrates the desired approach?
Finally, to summarise:
- custom codeblock
terminal - prompt parsing
-
- I suppose a prompt regex setting?
-
- if yes, also allow named capture groups to allow user setting of current directory / username / time and so on
- ARGV parsing
-
- command, arguments, comments, etc
-
- keep track of command for below
- Ability to implement parsing of output
-
- eg: pretty print
lsoutput
- eg: pretty print
-
- cf. GRC
Oh and the prompt settings would also include a prompt rewrite setting, to enable for example displaying only > ls /etc if the user sets this setting say > (?<command>) and the codeblock has the following content:
username@host $ ls /etc
Great! I'll address your question, then write out what I think the final spec should be:
The difference between the two implementations is that a custom codeblock is much more flexible since you can add elements wherever you want (i.e. extra lines for multiline prompts) whereas implementing it as a codeblock parameter like fold for example limits it to changing only a set few options without a major rewrite of how code blocks are decorated. Simply, codeblock parameters are used to markup existing code blocks and the existing framework doesn't allow for major changes whilst a custom codeblock can be much more flexible. (Also note implementing these changes in editing mode would require significant work with codemirror decorations that just aren't worth it). Codeblock parameters are things that decide things like whether code blocks should have headers or line numbers or generic additions to a rigorous structure. Is that any more clear?
I agree with most of your spec:
Custom codeblock terminal:
-
Codeblock Level Parameters
- Set default values for all of these if not manually set
- Should be able to manually update any of the codeblock level parameters at each line, I would do this as writing an extra line above each command line which modifies the codeblock level parameters for all subsequent lines i.,e.
<or something so doing a line with< user=barand then> whomiwould change the username tofoo - These could be used in a settings line i.e.
$USER:$HOSTNAME $TIME > $COMMANDto set what the output prompt should look like for each command line time- Default: Current Timetime_format- Default:hh:mm
username- Default:userhostname- Default:hoststarting_directory- Default:~(which equates to/Users/$USERwhen parsing forcd)- Any other obvious settings that should be ported from zsh prompts for example
-
Command Lines
- Should start with
>so easy to parse which lines are command lines and which are output lines (wouldn't hardcode this in case need to add more options later)
- Should start with
-
Output Lines
- Any line after initial params that doesn't start with
>or<etc.
- Any line after initial params that doesn't start with
-
Settings
- Prompt line - as above, a setting like
$USER:$HOSTNAME > $COMMANDto showmayurankv:foo > ls, which can be customised - ~Multiline prompt - whether prompt should be multiline?~ EDIT: This should be easy enough by allowing
\nin the prompt line - Transient prompt - as in p10k, should prompt only be shown for last command (kind of, a bit more complicated than this but easy enough to understand if you check p10k)
- Prompt line - as above, a setting like
-
Parsing commmands
- Add basic parsing for some commands, i.e.
whoami,cd, any others that are deterministic? - Any parsed output should be overwritten if an output is provided
- Potentially use information about command to prettify outputs, i.e. with ls, could parse multiple files into grid structure
- Add basic parsing for some commands, i.e.
This approach would mean, the codeblock should be parsed into blocks of 3: codeblock params starting with <, command line starting with > and (possibly multiple) output lines starting with anything else (should be able to escape these characters if needed though). Only the command line is required with the default output for most commands being nothing unless deterministic like whomi.
```terminal
< user=mayurankv, hostname=foo, start_dir=~/foo
> whoami
not_mayurankv (this would overwrite the default answer of mayurankv)
< user=still_not_mayurankv
> whomi
(no output line so insertion of "still_not_mayurankv")
> pwd
(automatically insert "foo")
> git commit
(no output since no output specified and not able to parse)
```
I'm not sure I understood your point about ARGV parsing and output parsing?
Is ARGV parsing for colourisation (tokenisation)? I was intending on highlighting using the existing shell modes (probably something else you can choose in settings). In terms of ls pretty printing, I think I follow but I'm not sure what you mean by the GRC point either, what would that be for?
Oh and the settings should probably get their own settings page under Codeblock Settings.
Oh! I was actually being a bit silly about the codeblock parameter vs custom codeblock. The main difference is the syntax parsing, i.e. you wouldn't want to have to put a > in front of every command in a shell codeblock with terminal parameter. But if we can implement the terminal codeblock, for other code blocks with the terminal parameter specified, we would just interrupt the normal processing and call the terminal processor treating each line as a command. (See the original post on this issue).
I've made a first draft to initially just do some basic tokenisation. It works fine in Editing mode but I cannot for the life of me figure out how to make it work in Reading mode.
Would you mind pointing me in the right direction?
Also let me know how bad this is, I've never written any TypeScript.
https://github.com/mayurankv/Obsidian-Code-Styler/compare/main...maa-x:Obsidian-Code-Styler:main
I'll tackle Terminal.ts once I start getting a better idea of what on earth it is I'm doing :smile:
Hey, really sorry for the delay, will get round to this very soon!
Update: Currently very busy with exams but will return to this when I can.
Any progress? Am also intrested in Terminal and bash. Also Batch would be nice :)
Guys, maybe for begin, would be good, just add icon support of Bash ;) ?