diff --git a/CHANGELOG.md b/CHANGELOG.md
index 012b60e5ff..477f73bb47 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -13,6 +13,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
 * new command-line option to override the default log file path (`--logfile`) [[@acuteenvy](https://github.com/acuteenvy)] ([#2539](https://github.com/gitui-org/gitui/pull/2539))
 * dx: `make check` checks Cargo.toml dependency ordering using `cargo sort` [[@naseschwarz](https://github.com/naseschwarz)]
 * add `use_selection_fg` to theme file to allow customizing selection foreground color [[@Upsylonbare](https://github.com/Upsylonbare)] ([#2515](https://github.com/gitui-org/gitui/pull/2515))
+* Add "go to line" command for the blame view [[@andrea-berling](https://github.com/andrea-berling)] ([#2262](https://github.com/extrawurst/gitui/pull/2262))
 
 ### Changed
 * improve syntax highlighting file detection [[@acuteenvy](https://github.com/acuteenvy)] ([#2524](https://github.com/extrawurst/gitui/pull/2524))
@@ -34,13 +35,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
 * use default shell instead of bash on Unix-like OS [[@yerke](https://github.com/yerke)] ([#2343](https://github.com/gitui-org/gitui/pull/2343))
 
 ### Added
-* add popups for viewing, adding, updating and removing remotes [[@robin-thoene](https://github.com/robin-thoene)] ([#2172](https://github.com/gitui-org/gitui/issues/2172))
-* support for `Copy Path` action in WSL [[@johnDeSilencio](https://github.com/johnDeSilencio)] ([#2413](https://github.com/gitui-org/gitui/pull/2413))
-* help popup scrollbar [[@wugeer](https://github.com/wugeer)] ([#2388](https://github.com/gitui-org/gitui/pull/2388))
 
-### Fixes
-* respect env vars like `GIT_CONFIG_GLOBAL` ([#2298](https://github.com/gitui-org/gitui/issues/2298))
-* Set `CREATE_NO_WINDOW` flag when executing Git hooks on Windows ([#2371](https://github.com/gitui-org/gitui/pull/2371))
+* support for "Copy Path" action in WSL [[@johnDeSilencio](https://github.com/johnDeSilencio)] ([#2413](https://github.com/extrawurst/gitui/pull/2413))
+* help popup scrollbar [[@wugeer](https://github.com/wugeer)](https://github.com/extrawurst/gitui/pull/2388))
+* add popups for viewing, adding, updating and removing remotes [[@robin-thoene](https://github.com/robin-thoene)] ([#2172](https://github.com/extrawurst/gitui/issues/2172))
 
 ## [0.26.3] - 2024-06-02
 
diff --git a/asyncgit/src/blame.rs b/asyncgit/src/blame.rs
index dcbb93aff0..0c99478512 100644
--- a/asyncgit/src/blame.rs
+++ b/asyncgit/src/blame.rs
@@ -14,7 +14,7 @@ use std::{
 };
 
 ///
-#[derive(Hash, Clone, PartialEq, Eq)]
+#[derive(Hash, Clone, PartialEq, Eq, Debug)]
 pub struct BlameParams {
 	/// path to the file to blame
 	pub file_path: String,
@@ -22,15 +22,17 @@ pub struct BlameParams {
 	pub commit_id: Option<CommitId>,
 }
 
+#[derive(Debug)]
 struct Request<R, A>(R, Option<A>);
 
-#[derive(Default, Clone)]
+#[derive(Debug, Default, Clone)]
 struct LastResult<P, R> {
 	params: P,
 	result: R,
 }
 
 ///
+#[derive(Debug, Clone)]
 pub struct AsyncBlame {
 	current: Arc<Mutex<Request<u64, FileBlame>>>,
 	last: Arc<Mutex<Option<LastResult<BlameParams, FileBlame>>>>,
diff --git a/src/app.rs b/src/app.rs
index 45037f048f..3a2dfd5dfb 100644
--- a/src/app.rs
+++ b/src/app.rs
@@ -10,16 +10,16 @@ use crate::{
 	options::{Options, SharedOptions},
 	popup_stack::PopupStack,
 	popups::{
-		AppOption, BlameFilePopup, BranchListPopup, CommitPopup,
-		CompareCommitsPopup, ConfirmPopup, CreateBranchPopup,
-		CreateRemotePopup, ExternalEditorPopup, FetchPopup,
-		FileRevlogPopup, FuzzyFindPopup, HelpPopup,
-		InspectCommitPopup, LogSearchPopupPopup, MsgPopup,
-		OptionsPopup, PullPopup, PushPopup, PushTagsPopup,
-		RemoteListPopup, RenameBranchPopup, RenameRemotePopup,
-		ResetPopup, RevisionFilesPopup, StashMsgPopup,
-		SubmodulesListPopup, TagCommitPopup, TagListPopup,
-		UpdateRemoteUrlPopup,
+		AppOption, BlameFileOpen, BlameFilePopup, BlameRequest,
+		BranchListPopup, CommitPopup, CompareCommitsPopup,
+		ConfirmPopup, CreateBranchPopup, CreateRemotePopup,
+		ExternalEditorPopup, FetchPopup, FileRevlogPopup,
+		FuzzyFindPopup, GotoLinePopup, HelpPopup, InspectCommitPopup,
+		LogSearchPopupPopup, MsgPopup, OptionsPopup, PullPopup,
+		PushPopup, PushTagsPopup, RemoteListPopup, RenameBranchPopup,
+		RenameRemotePopup, ResetPopup, RevisionFilesPopup,
+		StashMsgPopup, SubmodulesListPopup, TagCommitPopup,
+		TagListPopup, UpdateRemoteUrlPopup,
 	},
 	queue::{
 		Action, AppTabs, InternalEvent, NeedsUpdate, Queue,
@@ -112,6 +112,7 @@ pub struct App {
 	popup_stack: PopupStack,
 	options: SharedOptions,
 	repo_path_text: String,
+	goto_line_popup: GotoLinePopup,
 
 	// "Flags"
 	requires_redraw: Cell<bool>,
@@ -218,6 +219,7 @@ impl App {
 			stashing_tab: Stashing::new(&env),
 			stashlist_tab: StashList::new(&env),
 			files_tab: FilesTab::new(&env),
+			goto_line_popup: GotoLinePopup::new(&env),
 			tab: 0,
 			queue: env.queue,
 			theme: env.theme,
@@ -481,6 +483,7 @@ impl App {
 			msg_popup,
 			confirm_popup,
 			commit_popup,
+			goto_line_popup,
 			blame_file_popup,
 			file_revlog_popup,
 			stashmsg_popup,
@@ -544,7 +547,8 @@ impl App {
 			fetch_popup,
 			options_popup,
 			confirm_popup,
-			msg_popup
+			msg_popup,
+			goto_line_popup
 		]
 	);
 
@@ -691,6 +695,9 @@ impl App {
 			StackablePopupOpen::CompareCommits(param) => {
 				self.compare_commits_popup.open(param)?;
 			}
+			StackablePopupOpen::GotoLine(param) => {
+				self.goto_line_popup.open(param);
+			}
 		}
 
 		Ok(())
@@ -905,6 +912,26 @@ impl App {
 			InternalEvent::CommitSearch(options) => {
 				self.revlog.search(options);
 			}
+			InternalEvent::GotoLine(line) => {
+				if let Some(popup) = self.popup_stack.pop() {
+					if let StackablePopupOpen::BlameFile(params) =
+						popup
+					{
+						self.popup_stack.push(
+							StackablePopupOpen::BlameFile(
+								BlameFileOpen {
+									selection: Some(line),
+									blame: BlameRequest::KeepExisting,
+									..params
+								},
+							),
+						);
+					}
+					flags.insert(
+						NeedsUpdate::ALL | NeedsUpdate::COMMANDS,
+					);
+				}
+			}
 		};
 
 		Ok(flags)
diff --git a/src/components/revision_files.rs b/src/components/revision_files.rs
index 8a56071684..231c02094c 100644
--- a/src/components/revision_files.rs
+++ b/src/components/revision_files.rs
@@ -6,7 +6,7 @@ use super::{
 use crate::{
 	app::Environment,
 	keys::{key_match, SharedKeyConfig},
-	popups::{BlameFileOpen, FileRevOpen},
+	popups::{BlameFileOpen, BlameRequest, FileRevOpen},
 	queue::{InternalEvent, Queue, StackablePopupOpen},
 	strings::{self, order, symbol},
 	try_or_popup,
@@ -193,6 +193,7 @@ impl RevisionFilesComponent {
 					file_path: path,
 					commit_id: self.revision.as_ref().map(|c| c.id),
 					selection: None,
+					blame: BlameRequest::StartNew,
 				}),
 			));
 
diff --git a/src/components/status_tree.rs b/src/components/status_tree.rs
index 4fb762c1af..1d836bbe00 100644
--- a/src/components/status_tree.rs
+++ b/src/components/status_tree.rs
@@ -9,7 +9,7 @@ use crate::{
 	app::Environment,
 	components::{CommandInfo, Component, EventState},
 	keys::{key_match, SharedKeyConfig},
-	popups::{BlameFileOpen, FileRevOpen},
+	popups::{BlameFileOpen, BlameRequest, FileRevOpen},
 	queue::{InternalEvent, NeedsUpdate, Queue, StackablePopupOpen},
 	strings::{self, order},
 	ui::{self, style::SharedTheme},
@@ -456,6 +456,7 @@ impl Component for StatusTreeComponent {
 									file_path: status_item.path,
 									commit_id: self.revision,
 									selection: None,
+									blame: BlameRequest::StartNew,
 								},
 							),
 						));
diff --git a/src/keys/key_list.rs b/src/keys/key_list.rs
index 0f2909a2fe..24a9507a49 100644
--- a/src/keys/key_list.rs
+++ b/src/keys/key_list.rs
@@ -128,6 +128,7 @@ pub struct KeysList {
 	pub commit_history_next: GituiKeyEvent,
 	pub commit: GituiKeyEvent,
 	pub newline: GituiKeyEvent,
+	pub goto_line: GituiKeyEvent,
 }
 
 #[rustfmt::skip]
@@ -225,6 +226,7 @@ impl Default for KeysList {
 			commit_history_next: GituiKeyEvent::new(KeyCode::Char('n'),  KeyModifiers::CONTROL),
 			commit: GituiKeyEvent::new(KeyCode::Char('d'),  KeyModifiers::CONTROL),
 			newline: GituiKeyEvent::new(KeyCode::Enter,  KeyModifiers::empty()),
+			goto_line: GituiKeyEvent::new(KeyCode::Char('L'),  KeyModifiers::SHIFT),
 		}
 	}
 }
diff --git a/src/popups/blame_file.rs b/src/popups/blame_file.rs
index 273ca5ace3..c70b4720a7 100644
--- a/src/popups/blame_file.rs
+++ b/src/popups/blame_file.rs
@@ -30,12 +30,15 @@ use ratatui::{
 };
 use std::path::Path;
 
+use super::{goto_line::GotoLineContext, GotoLineOpen};
+
 static NO_COMMIT_ID: &str = "0000000";
 static NO_AUTHOR: &str = "<no author>";
 static MIN_AUTHOR_WIDTH: usize = 3;
 static MAX_AUTHOR_WIDTH: usize = 20;
 
-struct SyntaxFileBlame {
+#[derive(Debug, Clone)]
+pub struct SyntaxFileBlame {
 	pub file_blame: FileBlame,
 	pub styled_text: Option<SyntaxText>,
 }
@@ -54,7 +57,8 @@ impl SyntaxFileBlame {
 	}
 }
 
-enum BlameProcess {
+#[derive(Clone, Debug)]
+pub enum BlameProcess {
 	GettingBlame(AsyncBlame),
 	SyntaxHighlighting {
 		unstyled_file_blame: SyntaxFileBlame,
@@ -76,11 +80,18 @@ impl BlameProcess {
 	}
 }
 
+#[derive(Clone, Debug)]
+pub enum BlameRequest {
+	StartNew,
+	KeepExisting,
+}
+
 #[derive(Clone, Debug)]
 pub struct BlameFileOpen {
 	pub file_path: String,
 	pub commit_id: Option<CommitId>,
 	pub selection: Option<usize>,
+	pub blame: BlameRequest,
 }
 
 pub struct BlameFilePopup {
@@ -234,6 +245,16 @@ impl Component for BlameFilePopup {
 				)
 				.order(1),
 			);
+			out.push(
+				CommandInfo::new(
+					strings::commands::open_line_number_popup(
+						&self.key_config,
+					),
+					true,
+					has_result,
+				)
+				.order(1),
+			);
 		}
 
 		visibility_blocking(self)
@@ -307,6 +328,31 @@ impl Component for BlameFilePopup {
 							),
 						));
 					}
+				} else if key_match(
+					key,
+					self.key_config.keys.goto_line,
+				) {
+					let maybe_blame_result = &self
+						.blame
+						.as_ref()
+						.and_then(|blame| blame.result());
+					if maybe_blame_result.is_some() {
+						let max_line = maybe_blame_result
+							.expect("This can not be None")
+							.lines()
+							.len() - 1;
+						self.hide_stacked(true);
+						self.visible = true;
+						self.queue.push(InternalEvent::OpenPopup(
+							StackablePopupOpen::GotoLine(
+								GotoLineOpen {
+									context: GotoLineContext {
+										max_line,
+									},
+								},
+							),
+						));
+					}
 				}
 
 				return Ok(EventState::Consumed);
@@ -356,6 +402,7 @@ impl BlameFilePopup {
 						file_path: request.file_path,
 						commit_id: request.commit_id,
 						selection: self.get_selection(),
+						blame: BlameRequest::KeepExisting,
 					}),
 				));
 			}
@@ -371,11 +418,13 @@ impl BlameFilePopup {
 			file_path: open.file_path,
 			commit_id: open.commit_id,
 		});
-		self.blame =
-			Some(BlameProcess::GettingBlame(AsyncBlame::new(
-				self.repo.borrow().clone(),
-				&self.git_sender,
-			)));
+		if matches!(open.blame, BlameRequest::StartNew) {
+			self.blame =
+				Some(BlameProcess::GettingBlame(AsyncBlame::new(
+					self.repo.borrow().clone(),
+					&self.git_sender,
+				)));
+		}
 		self.table_state.get_mut().select(Some(0));
 		self.visible = true;
 		self.update()?;
@@ -438,7 +487,6 @@ impl BlameFilePopup {
 									),
 								},
 							);
-							self.set_open_selection();
 							self.highlight_blame_lines();
 
 							return Ok(());
@@ -449,6 +497,7 @@ impl BlameFilePopup {
 				}
 			}
 		}
+		self.set_open_selection();
 
 		Ok(())
 	}
@@ -722,7 +771,9 @@ impl BlameFilePopup {
 			self.open_request.as_ref().and_then(|req| req.selection)
 		{
 			let mut table_state = self.table_state.take();
-			table_state.select(Some(selection));
+			let max_line_number = self.get_max_line_number();
+			table_state
+				.select(Some(selection.clamp(0, max_line_number)));
 			self.table_state.set(table_state);
 		}
 	}
diff --git a/src/popups/file_revlog.rs b/src/popups/file_revlog.rs
index c946323b5d..3ad57074fc 100644
--- a/src/popups/file_revlog.rs
+++ b/src/popups/file_revlog.rs
@@ -28,7 +28,7 @@ use ratatui::{
 	Frame,
 };
 
-use super::{BlameFileOpen, InspectCommitOpen};
+use super::{BlameFileOpen, BlameRequest, InspectCommitOpen};
 
 const SLICE_SIZE: usize = 1200;
 
@@ -533,6 +533,7 @@ impl Component for FileRevlogPopup {
 									file_path: open_request.file_path,
 									commit_id: self.selected_commit(),
 									selection: None,
+									blame: BlameRequest::StartNew,
 								},
 							),
 						));
diff --git a/src/popups/goto_line.rs b/src/popups/goto_line.rs
new file mode 100644
index 0000000000..f900b2aa14
--- /dev/null
+++ b/src/popups/goto_line.rs
@@ -0,0 +1,180 @@
+use crate::{
+	app::Environment,
+	components::{
+		visibility_blocking, CommandBlocking, CommandInfo, Component,
+		DrawableComponent, EventState,
+	},
+	keys::{key_match, SharedKeyConfig},
+	queue::{InternalEvent, Queue},
+	strings,
+	ui::{self, style::SharedTheme},
+};
+
+use ratatui::{
+	layout::Rect,
+	style::{Color, Style},
+	widgets::{Block, Clear, Paragraph},
+	Frame,
+};
+
+use anyhow::Result;
+
+use crossterm::event::{Event, KeyCode};
+
+#[derive(Debug)]
+pub struct GotoLineContext {
+	pub max_line: usize,
+}
+
+#[derive(Debug)]
+pub struct GotoLineOpen {
+	pub context: GotoLineContext,
+}
+
+pub struct GotoLinePopup {
+	visible: bool,
+	input: String,
+	line_number: usize,
+	key_config: SharedKeyConfig,
+	queue: Queue,
+	theme: SharedTheme,
+	invalid_input: bool,
+	context: GotoLineContext,
+}
+
+impl GotoLinePopup {
+	pub fn new(env: &Environment) -> Self {
+		Self {
+			visible: false,
+			input: String::new(),
+			key_config: env.key_config.clone(),
+			queue: env.queue.clone(),
+			theme: env.theme.clone(),
+			invalid_input: false,
+			context: GotoLineContext { max_line: 0 },
+			line_number: 0,
+		}
+	}
+
+	pub fn open(&mut self, open: GotoLineOpen) {
+		self.visible = true;
+		self.context = open.context;
+	}
+}
+
+impl Component for GotoLinePopup {
+	///
+	fn commands(
+		&self,
+		out: &mut Vec<CommandInfo>,
+		force_all: bool,
+	) -> CommandBlocking {
+		if self.is_visible() || force_all {
+			out.push(
+				CommandInfo::new(
+					strings::commands::close_popup(&self.key_config),
+					true,
+					true,
+				)
+				.order(1),
+			);
+			out.push(
+				CommandInfo::new(
+					strings::commands::goto_line(&self.key_config),
+					true,
+					true,
+				)
+				.order(1),
+			);
+		}
+
+		visibility_blocking(self)
+	}
+
+	fn is_visible(&self) -> bool {
+		self.visible
+	}
+
+	///
+	fn event(&mut self, event: &Event) -> Result<EventState> {
+		if self.is_visible() {
+			if let Event::Key(key) = event {
+				if key_match(key, self.key_config.keys.exit_popup) {
+					self.visible = false;
+					self.input.clear();
+					self.queue.push(InternalEvent::PopupStackPop);
+				} else if let KeyCode::Char(c) = key.code {
+					if c.is_ascii_digit() || c == '-' {
+						self.input.push(c);
+					}
+				} else if key.code == KeyCode::Backspace {
+					self.input.pop();
+				} else if key_match(key, self.key_config.keys.enter) {
+					self.visible = false;
+					if self.invalid_input {
+						self.queue.push(InternalEvent::ShowErrorMsg(
+                            format!("Invalid input: only numbers between -{} and {} (included) are allowed (-1 denotes the last line, -2 denotes the second to last line, and so on)",self.context.max_line + 1, self.context.max_line))
+                            ,
+                        );
+					} else if !self.input.is_empty() {
+						self.queue.push(InternalEvent::GotoLine(
+							self.line_number,
+						));
+					}
+					self.queue.push(InternalEvent::PopupStackPop);
+					self.input.clear();
+					self.invalid_input = false;
+				}
+			}
+			match self.input.parse::<isize>() {
+				Ok(input) => {
+					let mut max_value_allowed_abs =
+						self.context.max_line;
+					// negative indices are 1 based
+					if input < 0 {
+						max_value_allowed_abs += 1;
+					}
+					let input_abs = input.unsigned_abs();
+					if input_abs > max_value_allowed_abs {
+						self.invalid_input = true;
+					} else {
+						self.invalid_input = false;
+						self.line_number = if input >= 0 {
+							input_abs
+						} else {
+							max_value_allowed_abs - input_abs
+						}
+					}
+				}
+				Err(_) => {
+					if !self.input.is_empty() {
+						self.invalid_input = true;
+					}
+				}
+			}
+			return Ok(EventState::Consumed);
+		}
+		Ok(EventState::NotConsumed)
+	}
+}
+
+impl DrawableComponent for GotoLinePopup {
+	fn draw(&self, f: &mut Frame, area: Rect) -> Result<()> {
+		if self.is_visible() {
+			let style = if self.invalid_input {
+				Style::default().fg(Color::Red)
+			} else {
+				self.theme.text(true, false)
+			};
+			let input = Paragraph::new(self.input.as_str())
+				.style(style)
+				.block(Block::bordered().title("Go to Line"));
+
+			let input_area = ui::centered_rect_absolute(15, 3, area);
+			f.render_widget(Clear, input_area);
+			f.render_widget(input, input_area);
+		}
+
+		Ok(())
+	}
+}
diff --git a/src/popups/mod.rs b/src/popups/mod.rs
index cb3ae1af74..fe746d9983 100644
--- a/src/popups/mod.rs
+++ b/src/popups/mod.rs
@@ -9,6 +9,7 @@ mod externaleditor;
 mod fetch;
 mod file_revlog;
 mod fuzzy_find;
+mod goto_line;
 mod help;
 mod inspect_commit;
 mod log_search;
@@ -28,7 +29,7 @@ mod tag_commit;
 mod taglist;
 mod update_remote_url;
 
-pub use blame_file::{BlameFileOpen, BlameFilePopup};
+pub use blame_file::{BlameFileOpen, BlameFilePopup, BlameRequest};
 pub use branchlist::BranchListPopup;
 pub use commit::CommitPopup;
 pub use compare_commits::CompareCommitsPopup;
@@ -39,6 +40,7 @@ pub use externaleditor::ExternalEditorPopup;
 pub use fetch::FetchPopup;
 pub use file_revlog::{FileRevOpen, FileRevlogPopup};
 pub use fuzzy_find::FuzzyFindPopup;
+pub use goto_line::{GotoLineOpen, GotoLinePopup};
 pub use help::HelpPopup;
 pub use inspect_commit::{InspectCommitOpen, InspectCommitPopup};
 pub use log_search::LogSearchPopupPopup;
diff --git a/src/queue.rs b/src/queue.rs
index 44268a851d..7e2054dc15 100644
--- a/src/queue.rs
+++ b/src/queue.rs
@@ -2,7 +2,7 @@ use crate::{
 	components::FuzzyFinderTarget,
 	popups::{
 		AppOption, BlameFileOpen, FileRevOpen, FileTreeOpen,
-		InspectCommitOpen,
+		GotoLineOpen, InspectCommitOpen,
 	},
 	tabs::StashingOptions,
 };
@@ -71,6 +71,8 @@ pub enum StackablePopupOpen {
 	InspectCommit(InspectCommitOpen),
 	///
 	CompareCommits(InspectCommitOpen),
+	///
+	GotoLine(GotoLineOpen),
 }
 
 pub enum AppTabs {
@@ -157,6 +159,8 @@ pub enum InternalEvent {
 	RewordCommit(CommitId),
 	///
 	CommitSearch(LogFilterSearchOptions),
+	///
+	GotoLine(usize),
 }
 
 /// single threaded simple queue for components to communicate with each other
diff --git a/src/strings.rs b/src/strings.rs
index c4cff10f70..62a2c6e564 100644
--- a/src/strings.rs
+++ b/src/strings.rs
@@ -1449,6 +1449,18 @@ pub mod commands {
 			CMD_GROUP_LOG,
 		)
 	}
+	pub fn open_line_number_popup(
+		key_config: &SharedKeyConfig,
+	) -> CommandText {
+		CommandText::new(
+			format!(
+				"Go to Line [{}]",
+				key_config.get_hint(key_config.keys.goto_line),
+			),
+			"go to a given line number in the blame view",
+			CMD_GROUP_GENERAL,
+		)
+	}
 	pub fn log_tag_commit(
 		key_config: &SharedKeyConfig,
 	) -> CommandText {
@@ -1870,4 +1882,15 @@ pub mod commands {
 			CMD_GROUP_LOG,
 		)
 	}
+
+	pub fn goto_line(key_config: &SharedKeyConfig) -> CommandText {
+		CommandText::new(
+			format!(
+				"Go To Line [{}]",
+				key_config.get_hint(key_config.keys.enter),
+			),
+			"Go to the given line",
+			CMD_GROUP_GENERAL,
+		)
+	}
 }
diff --git a/src/ui/syntax_text.rs b/src/ui/syntax_text.rs
index 8d758f20cc..3dac2a1cdf 100644
--- a/src/ui/syntax_text.rs
+++ b/src/ui/syntax_text.rs
@@ -23,10 +23,12 @@ use crate::{AsyncAppNotification, SyntaxHighlightProgress};
 
 pub const DEFAULT_SYNTAX_THEME: &str = "base16-eighties.dark";
 
+#[derive(Debug, Clone)]
 struct SyntaxLine {
 	items: Vec<(Style, usize, Range<usize>)>,
 }
 
+#[derive(Debug, Clone)]
 pub struct SyntaxText {
 	text: String,
 	lines: Vec<SyntaxLine>,
@@ -222,12 +224,13 @@ fn syntact_style_to_tui(style: &Style) -> ratatui::style::Style {
 	res
 }
 
+#[derive(Debug)]
 enum JobState {
 	Request((String, String)),
 	Response(SyntaxText),
 }
 
-#[derive(Clone, Default)]
+#[derive(Clone, Default, Debug)]
 pub struct AsyncSyntaxJob {
 	state: Arc<Mutex<Option<JobState>>>,
 	syntax: String,