diff --git a/assets/highlighting-tests/go.go b/assets/highlighting-tests/go.go new file mode 100644 index 00000000000..3b6bf3e0602 --- /dev/null +++ b/assets/highlighting-tests/go.go @@ -0,0 +1,108 @@ +// Comments +// Single-line comment + +/* + * Multi-line + * comment + */ + +package main + +import ( + "fmt" + "time" +) + +const Pi = 3.14 +var enabled = true + +// Numbers +42 +3.14 +.5 +1e10 +1.5e-3 +0xff +0XFF +0b1010 +0o77 +1_000_000 +2.5i + +// Constants +true +false +nil +iota + +// Strings and runes +'a' +'\n' +"double quotes with escape: \" \n \t \\" +`raw string +spans lines` + +// Control flow +func main() { + if enabled { + fmt.Println("enabled") + } else { + fmt.Println("disabled") + } + + for i := 0; i < 10; i++ { + if i == 5 { + continue + } + if i == 8 { + break + } + } + + switch now := time.Now().Weekday(); now { + case time.Saturday, time.Sunday: + fmt.Println("weekend") + default: + fmt.Println("weekday") + } + + values := []int{1, 2, 3} + for _, value := range values { + fmt.Println(value) + } + + ch := make(chan int, 1) + go func() { + defer close(ch) + ch <- 42 + }() + + select { + case msg := <-ch: + fmt.Println(msg) + default: + fmt.Println("no message") + } +} + +type Speaker interface { + Speak() string +} + +type Animal struct { + Name string +} + +func (a Animal) Speak() string { + return fmt.Sprintf("%s speaks", a.Name) +} + +func greet(name string) string { + return fmt.Sprintf("hello %s", name) +} + +var _ Speaker = Animal{} + +// Function calls +fmt.Println(greet("world")) +time.Now() diff --git a/assets/highlighting-tests/java.java b/assets/highlighting-tests/java.java new file mode 100644 index 00000000000..9e62f0da8fa --- /dev/null +++ b/assets/highlighting-tests/java.java @@ -0,0 +1,93 @@ +// Comments +// Single-line comment + +/* + * Multi-line + * comment + */ + +package example; + +import java.time.Instant; +import java.util.List; + +@Deprecated +public class Demo { + private static final double PI = 3.14; + private boolean enabled = true; + + // Numbers + int decimal = 42; + double fraction = 3.14; + double leadingDot = .5; + double scientific = 1.5e-3; + int hex = 0xff; + int binary = 0b1010; + long grouped = 1_000_000L; + float floatValue = 2.5f; + + // Constants + boolean yes = true; + boolean no = false; + Object nothing = null; + + // Strings and chars + char letter = 'a'; + char newline = '\n'; + String message = "double quotes with escape: \" \n \t \\"; + + public static void main(String[] args) { + Demo demo = new Demo(); + if (demo.enabled) { + System.out.println("enabled"); + } else { + System.out.println("disabled"); + } + + for (int i = 0; i < 10; i++) { + if (i == 5) { + continue; + } + if (i == 8) { + break; + } + } + + while (false) { + break; + } + + switch (args.length) { + case 0: + System.out.println("no args"); + break; + default: + System.out.println("args"); + } + + try { + demo.run(); + } catch (IllegalStateException ex) { + throw ex; + } finally { + System.out.println(Instant.now()); + } + } + + public void run() { + List names = List.of("Ada", "Grace"); + for (String name : names) { + System.out.println(greet(name)); + } + } + + public String greet(String name) { + return "hello " + name; + } +} + +record Point(int x, int y) {} + +sealed interface Shape permits Circle {} + +final class Circle implements Shape {} diff --git a/assets/highlighting-tests/markdown.md b/assets/highlighting-tests/markdown.md index 555b182f961..05f7ffa2155 100644 --- a/assets/highlighting-tests/markdown.md +++ b/assets/highlighting-tests/markdown.md @@ -66,12 +66,30 @@ Reference: ![Logo][logo-ref] echo "Hello, world" | tr a-z A-Z ``` +```go +package main + +import "fmt" + +func main() { + fmt.Println("hello") +} +``` + ```javascript export function greet(name) { return `hello ${name}`; } ``` +```java +class Demo { + static void main(String[] args) { + System.out.println("hello"); + } +} +``` + ```json { "name": "gfm-kitchen-sink", diff --git a/crates/lsh/definitions/go.lsh b/crates/lsh/definitions/go.lsh new file mode 100644 index 00000000000..920fc19cea5 --- /dev/null +++ b/crates/lsh/definitions/go.lsh @@ -0,0 +1,59 @@ +#[display_name = "Go"] +#[path = "**/*.go"] +pub fn go() { + until /$/ { + yield other; + + if /\/\/.*/ { + yield comment; + } else if /\/\*/ { + loop { + yield comment; + await input; + if /\*\// { + yield comment; + break; + } + } + } else if /'/ { + until /$/ { + yield string; + if /\\./ {} + else if /'/ { yield string; break; } + await input; + } + } else if /"/ { + until /$/ { + yield string; + if /\\./ {} + else if /"/ { yield string; break; } + await input; + } + } else if /`/ { + loop { + yield string; + if /[^`]*/ {} + if /`/ { yield string; break; } + await input; + } + } else if /(?:break|case|continue|default|defer|else|fallthrough|for|goto|if|range|return|select|switch)\>/ { + yield keyword.control; + } else if /(?:chan|const|func|go|import|interface|map|package|struct|type|var)\>/ { + yield keyword.other; + } else if /(?:true|false|iota|nil)\>/ { + yield constant.language; + } else if /(?i:-?(?:0x[\da-fA-F_]+|0b[01_]+|0o[0-7_]+|[\d_]+\.?[\d_]*|\.[\d_]+)(?:p[+-]?[\d_]+|e[+-]?[\d_]+)?i?)/ { + if /\w+/ { + // Invalid numeric literal + } else { + yield constant.numeric; + } + } else if /(\w+)\s*\(/ { + yield $1 as method; + } else if /\w+/ { + // Gobble word chars to align the next iteration on a word boundary. + } + + yield other; + } +} diff --git a/crates/lsh/definitions/java.lsh b/crates/lsh/definitions/java.lsh new file mode 100644 index 00000000000..e203eecfd2a --- /dev/null +++ b/crates/lsh/definitions/java.lsh @@ -0,0 +1,56 @@ +#[display_name = "Java"] +#[path = "**/*.java"] +pub fn java() { + until /$/ { + yield other; + + if /\/\/.*/ { + yield comment; + } else if /\/\*/ { + loop { + yield comment; + await input; + if /\*\// { + yield comment; + break; + } + } + } else if /'/ { + until /$/ { + yield string; + if /\\./ {} + else if /'/ { yield string; break; } + await input; + } + } else if /"/ { + until /$/ { + yield string; + if /\\./ {} + else if /"/ { yield string; break; } + await input; + } + } else if /(?:break|case|catch|continue|default|do|else|finally|for|if|return|switch|throw|throws|try|while)\>/ { + yield keyword.control; + } else if /(?:abstract|assert|class|enum|extends|final|implements|import|instanceof|interface|module|native|new|package|private|protected|public|record|sealed|static|strictfp|super|synchronized|this|transient|volatile)\>/ { + yield keyword.other; + } else if /(?:boolean|byte|char|double|float|int|long|short|void|var)\>/ { + yield keyword.other; + } else if /(?:true|false|null)\>/ { + yield constant.language; + } else if /@\w+/ { + yield markup.link; + } else if /(?i:-?(?:0x[\da-fA-F_]+|0b[01_]+|[\d_]+\.?[\d_]*|\.[\d_]+)(?:p[+-]?[\d_]+|e[+-]?[\d_]+)?[dfl]?)/ { + if /\w+/ { + // Invalid numeric literal + } else { + yield constant.numeric; + } + } else if /(\w+)\s*\(/ { + yield $1 as method; + } else if /\w+/ { + // Gobble word chars to align the next iteration on a word boundary. + } + + yield other; + } +} diff --git a/crates/lsh/definitions/markdown.lsh b/crates/lsh/definitions/markdown.lsh index 77a005fe925..5bd91395dc9 100644 --- a/crates/lsh/definitions/markdown.lsh +++ b/crates/lsh/definitions/markdown.lsh @@ -28,6 +28,16 @@ pub fn markdown() { if /.*/ {} } } + } else if /(?i:go|golang)/ { + loop { + await input; + if /\s*```/ { + return; + } else { + go(); + if /.*/ {} + } + } } else if /(?i:diff)/ { loop { await input; @@ -50,6 +60,16 @@ pub fn markdown() { if /.*/ {} } } + } else if /(?i:java)/ { + loop { + await input; + if /\s*```/ { + return; + } else { + java(); + if /.*/ {} + } + } } else if /(?i:json)/ { loop { await input;