wez / wezterm

A GPU-accelerated cross-platform terminal emulator and multiplexer written by @wez and implemented in Rust
https://wezfurlong.org/wezterm/
Other
16.38k stars 729 forks source link

Consider syntax highlighting like MobaXterm #4348

Open lwbt opened 11 months ago

lwbt commented 11 months ago

Is your feature request related to a problem? Please describe. It's not a problem with WezTerm. WezTerm is fine as it is, but there may be an opportunity in the market for WezTerm (to show that WezTerm is superior cross platform software; to secure funding for maintenance and development of WezTerm).

Describe the solution you'd like MobaXterm offers rudimentary syntax highlighting (Standard Keywords; Unix shell script; Cisco; Perl; SQL) independent from the shell or program used. \ https://mobaxterm.mobatek.net/documentation.html#3_2_13

Describe alternatives you've considered MobaXterm is the only application where I have seen syntax highlighting, which from my point of view, is in the domain of the shell (e.g. bash, pwsh, fish) or an application (e.g. vim) and not the terminal emulator. You may close this issue if you think that output of a shell or program running inside of a terminal emulator like WezTerm should not be modified by the terminal emulator.

Additional context Use case: I have come across several environments with poorly configured and administered servers where developers and administrators have to modify scripts and data without syntax highlighting. This can be clearly identified as institutional malpractice. Eventually vim or some other kind of widely used and actively maintained FOSS software package can supply a wide range of syntax highlighting definitions to WezTerm where said developers and administrators are afraid of replacing vim-tiny with vim, or where where modifications to the environment are not possible at all. In such environments MobaXterm seems to have gained a reputation for being superior software, while it actually is playing some cheap tricks nobody else seems to have thought of. No, please don't copy every possible feature of MobaXterm! Syntax highlighting seems to be the best part of it, while most other features are considered to be user hostile anti-features (like a screensaver which cannot be turned off in the non-professional version, or games nobody asked for) for a terminal emulator from my point of view.

bew commented 11 months ago

What kind of syntax highlights is mobaxterm doing? Static text with color? Regex with special groups?

lwbt commented 11 months ago

It looks to be Regex

Okay let's start with the most useful one from my point of view:

[CustomSyntax]
Name=Custom: Unix shell
UseRegex=1
Underline=[^A-Za-z_&-](http(s)?://[A-Za-z0-9_.&?=%~#{}()@+-]+:?[A-Za-z0-9_./&?=%~#{}()@+-]+)[^A-Za-z0-9_-]
Red=[^\](\$\([^(\))]+\)|`[^ `][^`]+`)[^¨]
Green=(¨( *)?#[^¨]+)+
Yellow=[^\](\$[\?@\$][^¨]|\$\(\([^(\))]+\)\)[^¨]|\$\{[^\}]+\}[^¨]|\$\[[^]]+\][^¨]|\$[A-Za-z_0-9]+[^A-Za-z_0-9])
Blue=[^\](\\(033|e|E)\[(1;)?(0|30|31|32|33|34|35|36)m|/dev/null|\|\||\&\&)[^¨]
Magenta=[ ;¨\(](for(each)?|while|done|if|then|else|elif|fi|case|esac|endif)[ ;¨\)]
Cyan=[ ;¨](builtin )?(setenv|export|unset|ulimit|builtin|shopt|unalias|alias|function|echo|printf)[ ;¨]
Blinking=
CaseSensitive=1

This is what I got when I tried to export the defaults for shell script as a custom profile.

The following is the default, which I see on most users desktops:

[CustomSyntax]
Name=Custom: OK/warning/error keywords
UseRegex=1
Underline=[^A-Za-z_&-](http(s)?://[A-Za-z0-9_.&?=%~#{}()@+-]+:?[A-Za-z0-9_./&?=%~#{}()@+-]+)[^A-Za-z0-9_-]
Red=([^A-Za-z_&-]((bad|wrong|incorrect|improper|invalid|unsupported|bad)( file| memory)? (descriptor|alloc(ation)?|addr(ess)?|owner(ship)?|arg(ument)?|param(eter)?|setting|length|filename)|not properly|improperly|(operation |connection |authentication |access |permission )?(denied|disallowed|not allowed|refused|problem|failed|failure|not permitted)|no [A-Za-z]+( [A-Za-z]+)? found|invalid|unsupported|not supported|seg(mentation )?fault|corruption|corrupted|corrupt|overflow|underrun|not ok|unimplemented|unsuccessfull|not implemented|permerrors?|fehlers?|errore|errors?|erreurs?|fejl|virhe|gre<9a>ka|erro|fel|\(ee\)|\(ni\))[^A-Za-z_-]|[=>"':.,;({\[][ ]*(false|no|ko)[ ]*[]=>"':.,;)} ])
Green=([^A-Za-z_&-](accepted|allowed|enabled|connected|erfolgreich|exitoso|successo|sucedido|framgångsrik|successfully|successful|succeeded|success)[^A-Za-z_-]|[=>"':.,;({\[][ ]*(true|yes|ok)[ ]*[]=>"':.,;)} ])
Yellow=[^A-Za-z_&-](\[\-w[A-Za-z-]+\]|caught signal [0-9]+|cannot|(connection (to (remote host|[a-z0-9.]+) )?)?(closed|terminated|stopped|not responding)|exited|no more [A-Za-z] available|unexpected|(command |binary |file )?not found|ooo?o?o?ps|out of (space|memory)|low (memory|disk)|unknown|disabled|disconnected|deprecated|refused|disconnect(ion)?|advertencia|avvertimento|attention|warnings?|achtung|exclamation|alerts?|warnungs?|advarsel|pedwarn|aviso|varoitus|upozorenje|peringatan|uyari|varning|avertissement|\(ww\)|\(\?\?\)|could not|unable to)[^A-Za-z_-]
Blue=
Magenta=[^0-9A-Za-z_&-](localhost|([1-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-4])\.[0-9]+\.[0-9]+\.[0-9]+|null|none)[^0-9A-Za-z_-]
Cyan=[^A-Za-z_&-](last (failed )?login:|launching|checking|loading|creating|building|important|booting|starting|notice|informational|informationen|informazioni|informação|oplysninger|informations?|info|información|informasi|note|\(ii\)|\(\!\!\))[^A-Za-z_-]
Blinking=
CaseSensitive=0

Note that gre<9a>ka here seems to be another encoding issue. I first opened the files with Gedit where some characters where not displayed like in Notepad++ on Windows and then I tried to use vim which comes closer to what I see in Notepad++ with this exception.

Network:

[CustomSyntax]
Name=Custom: Cisco (network)
UseRegex=1
Underline=[^A-Za-z_&-](http(s)?://[A-Za-z0-9_.&?=%~#{}()@+-]+:?[A-Za-z0-9_./&?=%~#{}()@+-]+)[^A-Za-z0-9_-]
Red=(¨( *)?no | down |[^A-Za-z0-9](disabled|unknown|fault|shutdown|disconnected|error|failed|denied|not permitted|disallowed|not allowed|refused|problem|failure|not permitted|notconnect)[^A-Za-z0-9])
Green=([^A-Za-z0-9](enabled|connected|up|yes|ok)[^A-Za-z0-9]|¨( *)?(description|(host)?name(if)?|version) [^¨]+)
Yellow=[^A-Za-z0-9]([0-9a-f][0-9a-f](:|-)[0-9a-f][0-9a-f](:|-)[0-9a-f][0-9a-f](:|-)[0-9a-f][0-9a-f](:|-)[0-9a-f][0-9a-f](:|-)[0-9a-f][0-9a-f]|localhost|([1-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-4])\.[0-9]+\.[0-9]+\.[0-9]+|vlan[0-9]+|([a-z]+thernet|gi)[0-9]+(\/[0-9]+)*)[^A-Za-z0-9]
Blue=(¨( *)?\![^¨]+)+
Magenta=[^A-Za-z0-9](policy-map|class|global|logging( event)?|(allocate-)?interface|failover|static|security-level|service(-policy)?|spanning-tree|switchport)[^A-Za-z0-9]
Cyan=[^A-Za-z0-9](\%link-[0-9]+-updown|(allowed )?(private-)?vlan(-range)?|route|access-(list|group)|port-forward|mtu|show|encapsulation|rate-limit|speed|duplex|autoneg|snmp-server|media-type|ip( address)?|monitor( session)?)[^A-Za-z0-9]
Blinking=
CaseSensitive=0

Perl:

[CustomSyntax]
Name=Custom: Perl
UseRegex=1
Underline=[^A-Za-z_&-](http(s)?://[A-Za-z0-9_.&?=%~#{}()@+-]+:?[A-Za-z0-9_./&?=%~#{}()@+-]+)[^A-Za-z0-9_-]
Red=[^A-Za-z_&-](exit|unlink|die|use [a-z0-9]+(::[^ ;:]+)*|each|exists|keys|values|tie|tied|untie|binmode|close|closedir|eof|fileno|getc|printf|readdir|readline|readpipe|select|stat|tell|telldir|write)[^A-Za-z_&-]
Green=(¨( *)?#[^¨]+)+
Yellow=[^A-Za-z_&-](=>|switch|eq|ne|gt|lt|ge|le|cmp|not|and|or|xor|err|defined|undef|and|or|not|bless|ref|chdir|delete|find|rmdir|rename|mkdir|open|print|my|local|our|chomp|chop|chr|crypt|index|lcfirst|lc|length|ord|pack|reverse|rindex|sprintf|substr|ucfirst|uc|split|splice|unshift|shift|push|pop|split|join|grep|map|sort)[^A-Za-z_&-]
Blue=[^A-Za-z_&-](sigtrap|subs|vars|warnings|utf8|byte|base|fields|import|alarm)[^A-Za-z_&-]
Magenta=[^A-Za-z_&-](elsif|unless|else|if|while|foreach|for|until|continue|do|begin|end|check|init|goto|return|last|next|redo)[^A-Za-z_&-]
Cyan=[^\](\$[\?@\$][^¨]|\$\(\([^(\))]+\)\)[^¨]|\$\{[^\}]+\}[^¨]|\$\[[^]]+\][^¨]|\$[A-Za-z_0-9]+[^A-Za-z_0-9])
Blinking=
CaseSensitive=0

SQL:

[CustomSyntax]
Name=Custom: SQL
UseRegex=0
Underline=
Red=error,warning,cancel,disable,drop,abort,after,asc,attach,before,begin,cascade,cluster,conflict,copy,cross,database,deferred,delimiters,desc,detach,each,end,explain,fail,for,full,ignore,immediate,initially,inner,instead,key,left,match,natural,of,offset,outer,pragma,raise,replace,restrict,right,row,statement,temp,temporary,trigger,vacuum,view,cancelled
Green=enable,mysql,postgresql,postgre,oracle,server,database,db,ok,successful,success
Yellow=lock,unlock,databases,dump,echo,exit,explain,header,help,indices,mode,mode insert,nullvalue,output,output stdout,prompt,quit,read,separator,show,schema,tables,timeout,width,default,notnull,not null,null,not,auto_increment
Blue=
Magenta=charset,engine,table,dumping,dropping,_rowid_,main,oid,rowid,sqlite_master,sqlite_temp_master
Cyan=if exists,inner join,alter,all,and,as,between,by,case,collate,commit,constraint,create,deferrable,delete,distinct,else,except,foreign,from,glob,group,having,check,in,index,insert,intersect,into,is,isnull,join,like,limit,on,or,order,primary,references,rollback,select,set,then,transaction,union,unique,update,using,values,when,where
Blinking=
CaseSensitive=0
wez commented 11 months ago

My knee-jerk response to this was "no!" because there are challenges with matching text at output time (mostly stemming from the fact that output is not guaranteed to be sequentially emitted).

If you consider implicit hyperlinks though, they match text at render time based on regex, and then augment the attributes in the matched cells.

What I think might be interesting here is if semantic zones are expanded so that they can have some metadata (like Content-Type) that informs what is present in the zone.

Then there could be some configuration that maps the zone type and content type to a profile/theme that could be applied to that block when it is rendered.

Care would need to be taken to avoid making the render performance worse by adding this in though; it is not free to compute the extents of semantic zones, and a simplistic implementation of this feature would break some of the caching we have today.

So: this might be interesting, but it is a bit of a niche feature, and it is a decent amount of work.

James-SSR commented 9 months ago

What about more trivial case? We already have search pattern being highlighted. Could it be made persistent? For example hit search keybind, enter pattern/text, hit keybind (not Esc): text stays highlighted, we continue to work, patterns highlight as the new lines added. Is there same performance considerations? In my case, i only care for one pattern highlight (for example serial console output or output form device on telnet, where you have stream of text and cant filter it otherwise). If it is possible to make multiple such "searches" it could be partially adapted for current PR and mentioned #4593.

Also kitty implemented something similar. Maybe take a look for inspiration?

eugenov commented 6 months ago

but it is a bit of a niche feature

Well, I don't think so. This made Mobaxterm so popular (not only by this feature, though). There are too few terminals/ssh clients that support syntax highlight, I can count it using fingers of one hand (tabby+highlight plugin, mobaxterm, xshell and remote desktop manager)

pidgeon777 commented 6 months ago

I would also be greatly interested in some functionality which allows to highlight buffer keywords based on regex. Also allowing to navigate them with shortucts.

This functionality is missing from alacritty, too.

madsholme commented 2 months ago

tabby has that feature. would love it in wezterm

revdandom commented 1 month ago

This was one of my favorite features in iTerm and when I moved away from a Mac, I found myself writing shell functions to highlight patterns. It was great until I forgot to copy my functions over to a new machine or just plain forgot to filter commands through my highlight functions. And with WezTerm scripting, you could easily toggle the type of patterns highlighted for different contexts.

tjames192 commented 1 week ago

i'll 2nd this, i am also looking forward to this kind of feature. perusing around; i found this terminal rust implementation though i haven't yet tried myself. maybe this kind of implementation could work? https://github.com/kumavale/sisterm