链接:https://github.com/sharkdp/bat

前文传送:

  • 【探索Linux命令行】从基础指令到高级管道操作的介绍与实践
  • 【Linux命令行】从时间管理->文件查找压缩的指令详解
  • 【Linux】1w详解如何实现一个简单的shell

docs:bat

在这里插入图片描述

bat 是一个**命令行文件查看器**,能够美化代码和文本文件。

它的工作原理是接收原始输入,智能地检测编程语言,然后应用生动的语法高亮和其他视觉装饰(如行号或 Git 变更)。

最终,增强后的输出会*直接显示或通过分页器(如 less)*输出,从而提供更好的查看体验。

可视化

在这里插入图片描述

章节

  1. 控制器
  2. 输入管理
  3. 输出处理
  4. 配置 (Config)
  5. 高亮资源
  6. 语法映射
  7. 行范围处理
  8. 打印器

第一章:控制器

欢迎来到 bat 🐻‍❄️

如果你想通过漂亮的语法高亮、行号等功能让你的代码和文本文件更加清晰,那么你来对地方了ovo。

在这第一章中,我们将介绍“控制器”,它是 bat 强大显示功能背后的核心大脑。

控制器解决了什么问题?

假设我们有一个纯文本文件,比如一个 Python 脚本,我们想在屏幕上显示它。不仅仅是原始文本,而是带有各种装饰效果:不同关键词的鲜艳颜色、清晰的行号,甚至可能还有版本控制中的变更标记。如何从一个简单的文本文件变成这样丰富、视觉上吸引人的输出呢?

这就是控制器的作用!它就像是整个显示操作的项目经理。我们告诉它想要显示哪些文件以及如何显示(我们的“配置”),然后控制器负责确保一切正确执行。

本章的目标是理解控制器如何协调这一过程,将一个简单的文件准备好,以便进行漂亮的显示。

控制器:我们的项目经理

控制器本身并不直接执行高亮或行号添加。相反,它协调所有其他专业化的组件。可以将其视为:

  • 协调者:确保从读取文件到最终显示的每一步都按正确顺序进行。
  • 指挥官:根据我们的设置告诉其他组件该做什么。
  • 错误处理者:如果出现问题(例如文件无法找到),控制器会捕获错误。

使用控制器

虽然 bat 提供了一个用户友好的 PrettyPrinter 来处理常见任务,但直接理解 Controller 有助于掌握核心逻辑。让我们看一个基本示例,展示如何使用 batController 来显示一个简单的 Rust 文件。

以下是一个最小化的代码片段,灵感来自 bat 的示例,直接使用 Controller 将文件内容(这里是 examples/buffer.rs 本身)打印到一个字符串缓冲区:

use bat::{assets::HighlightingAssets, // 管理语法定义和主题config::Config,            // 我们的显示偏好controller::Controller,    // 协调者!output::OutputHandle,      // 输出目标Input,                     // 表示输入文件
};fn main() {let mut buffer = String::new(); // 输出将存储在这里let config = Config {colored_output: true, // 是的,我们需要颜色!..Default::default()};let assets = HighlightingAssets::from_binary(); // 加载内置的高亮信息let controller = Controller::new(&config, &assets); // 创建控制器// 为当前文件创建输入let input = Input::from_file(file!());// 运行控制器处理并打印输入controller.run(vec![input.into()], // 提供输入文件Some(OutputHandle::FmtWrite(&mut buffer)), // 告诉它写入字符串缓冲区).unwrap();println!("{buffer}"); // 最终打印缓冲区中的结果
}

说明:

  1. 我们设置了一个名为 bufferString,用于存储高亮后的输出
  2. 我们创建了一个 Config 对象,其中包含所有偏好设置,比如是否需要彩色输出。..Default::default() 为其他设置填充默认值。
  3. HighlightingAssets::from_binary() 加载所有内置的语法定义(例如如何高亮 Rust、Python 等)和颜色主题。
  4. 然后,我们使用 Controller::new(&config, &assets) 创建控制器。我们提供偏好设置(config)和高亮规则(assets)。
  5. 我们定义要显示的内容为 Input。这里,Input::from_file(file!()) 表示我们要求 bat 处理包含这段代码的 Rust 文件!
  6. 最后,controller.run(...) 是魔法发生的地方。我们给控制器提供 input(要处理的文件),并告诉它将输出写入 buffer 通过 OutputHandle

运行这段代码时,bat 会处理 examples/buffer.rs 文件,根据 Rust 规则和默认主题应用语法高亮,并将格式化后的输出存储在 buffer 中,然后打印到控制台。

在这里插入图片描述

控制器内部工作原理

让我们揭开控制器的面纱,看看调用 controller.run() 时发生了什么。控制器作为我们的项目经理,与多个专业团队协调完成任务。

以下是简化的步骤分解:

  1. 接收请求:我们(程序员)告诉控制器处理一组文件,并提供特定配置。
  2. 准备输入:对于每个文件,控制器要求输入管理团队读取其内容。该团队负责打开文件、从标准输入读取,甚至处理字节数组。
  3. 收集设置:控制器使用我们提供的 Config(即配置)。Config 包含所有指令:“使用这个颜色主题”、“显示行号”、“换行长行”等。
  4. 加载高亮信息:控制器查询 HighlightingAssets 以找到正确的语法定义(例如,“这是一个 Rust 文件,这是它的关键词和结构”)和选择的颜色主题。
  5. 启动打印机:对于每个输入文件的每一行,控制器将原始行连同所有配置和高亮规则交给打印机团队。打印机是实际应用颜色、添加行号并格式化文本的艺术家。
  6. 定向输出:打印机的格式化输出随后发送到输出处理。这可能意味着直接写入终端,或通过分页程序(如 less)以便于浏览大文件。
  7. 处理错误:如果任何团队遇到问题(例如文件不可读),控制器会捕获并报告。

以下是描述这一流程的序列图:

在这里插入图片描述

深入代码

让我们看看 bat 源代码中控制器的结构。

首先是 Controller 结构体本身(来自 src/controller.rs):

// src/controller.rs
pub struct Controller<'a> {config: &'a Config<'a>,assets: &'a HighlightingAssets,// ... 其他字段(用于 lessopen 特性的预处理器)
}

说明:

  • config: &'a Config<'a>:这是对配置对象的引用,包含用户的所有偏好设置。控制器需要这些指令来知道如何显示文件。
  • assets: &'a HighlightingAssets:这是对 HighlightingAssets 的引用,包含所有语法定义和主题。这告诉控制器应用哪些高亮规则和颜色。

接下来是控制器的构造函数(new)和主要的 run 方法:

// src/controller.rs
impl Controller<'_> {pub fn new<'a>(config: &'a Config, assets: &'a HighlightingAssets) -> Controller<'a> {Controller {config,assets,// ... 初始化其他字段}}pub fn run(&self, inputs: Vec<Input>, output_handle: Option<OutputHandle<'_>>) -> Result<bool> {// ... 设置输出 ...let mut no_errors: bool = true;for (index, input) in inputs.into_iter().enumerate() {let result = if input.is_stdin() {// 处理标准输入self.print_input(input, &mut writer, io::stdin().lock(), identifier, is_first)} else {// 处理文件输入self.print_input(input, &mut writer, io::empty(), identifier, is_first)};if let Err(error) = result {// ... 错误处理 ...no_errors = false;}}Ok(no_errors)}fn print_input<R: BufRead>(&self,input: Input,writer: &mut OutputHandle,stdin: R,stdout_identifier: Option<&Identifier>,is_first: bool,) -> Result<()> {let mut opened_input = input.open(stdin, stdout_identifier)?;// ... 可能获取 git diff ...let mut printer: Box<dyn Printer> = /* ... 创建 InteractivePrinter 或 SimplePrinter ... */;self.print_file(&mut *printer,writer,&mut opened_input,!is_first,// ... line_changes ...)}// ... 其他辅助方法如 print_file, print_file_ranges ...
}

说明:

  1. Controller::new:这是创建控制器的方式。只需传递 ConfigHighlightingAssets
  2. Controller::run:这是启动处理的主要方法。
    • 它准备 output_type,确定输出去向(例如直接到终端或通过分页程序)。这将在输出处理中进一步讨论。
    • 然后遍历每个提供的 Input 文件或流。
    • 对于每个输入,调用 self.print_input
  3. Controller::print_input:此方法处理单个输入的流程:
    • 使用输入管理组件 open 输入,使其内容可读。
    • 创建一个 printerSimplePrinterInteractivePrinter)。printer 是实际根据 ConfigHighlightingAssets 对原始文本应用样式的组件。我们将在打印机章节深入探讨。
    • 最后调用 self.print_file,将逐行打印的实际工作委托给选定的 printer

这表明控制器确实是核心枢纽,将 ConfigHighlightingAssets、输入管理、输出处理和打印机结合在一起完成任务。

结论

在本章中,我们了解到控制器是 bat 项目的核心协调者。

它像项目经理一样,接收我们的配置和文件列表,然后指导其他专业组件读取、处理、高亮并漂亮地显示代码。虽然它不直接执行细节工作,但其协调角色bat 的功能至关重要。

现在我们已经理解了控制器在显示流程中的协调作用,下一步是了解 bat 如何处理我们想要显示的文件。在下一章中,我们将深入探讨输入管理,学习 bat 如何高效读取文件和其他数据源。

下一章:输入管理

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/pingmian/95934.shtml
繁体地址,请注明出处:http://hk.pswp.cn/pingmian/95934.shtml
英文地址,请注明出处:http://en.pswp.cn/pingmian/95934.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

无线自动信道调整

通过信道调整功能&#xff0c;可以保证每个AP 能够分配到最优的信道&#xff0c;尽可能地 减少和避免相邻信道干扰&#xff0c;而且通过实时信道检测&#xff0c;使AP 实时避开雷达&#xff0c;微波炉等干扰源。 动态信道调整能够实现通信的持续进行&#xff0c;为网络的可靠传…

ios面试八股文

​​Swift 语言特性​​&#xff1a;请解释一下 struct和 class的主要区别。特性​​​​struct (值类型)​​​​class (引用类型)​​​​类型本质​​值类型 (复制时创建独立副本)引用类型 (复制时共享同一实例)​​内存分配​​通常在栈上 (更快速)在堆上 (需要ARC管理)​​…

IntelliJ IDEA 2023更新git凭据

背景&#xff1a;已知原来从远程仓库获取的项目&#xff0c;需要更新git用户和密码&#xff0c;但是又不想删除本地项目环境&#xff08;不想重新获取新建项目&#xff09;。报错&#xff1a;remote: HTTP Basic: Access denied. The provided password or token is incorrect …

Docker 容器 OOM:从资源监控到JVM调优的实战记录

人们眼中的天才之所以卓越非凡&#xff0c;并非天资超人一等而是付出了持续不断的努力。1万小时的锤炼是任何人从平凡变成超凡的必要条件。———— 马尔科姆格拉德威尔 &#x1f31f; Hello&#xff0c;我是Xxtaoaooo&#xff01; &#x1f308; “代码是逻辑的诗篇&#xff…

【开题答辩全过程】以 基于微信小程序的宠物领养系统为例,包含答辩的问题和答案

个人简介一名14年经验的资深毕设内行人&#xff0c;语言擅长Java、php、微信小程序、Python、Golang、安卓Android等开发项目包括大数据、深度学习、网站、小程序、安卓、算法。平常会做一些项目定制化开发、代码讲解、答辩教学、文档编写、也懂一些降重方面的技巧。感谢大家的…

【可信数据空间-连接器状态监控-Java代码集成】

可信数据空间-连接器状态监控-Java代码集成一、 核心概念1. Micrometer2. Micrometer Registry Prometheus3.Prometheus二、 依赖配置 (Maven)三、 集成步骤与代码示例场景一&#xff1a;在 Spring Boot 应用中集成&#xff08;最简单&#xff09;1. 添加依赖&#xff08;如上所…

反编译分析C#闭包

一、问题描述&#xff1a;比如有这样的代码&#xff1a;它的输出结果是 3&#xff0c;3&#xff0c;3。通过搜索得知这一现象是因为C#闭包导致的.我们借助ILSpy看下IL中间代码&#xff0c;首先它生成了一个名叫DisplayClass的类&#xff0c;类中定义了i的字段主代码&#xff1a…

卷积神经网络(CNN):从图像识别原理到实战应用的深度解析

目录一.CNN的技术必要性&#xff1a;破解传统图像处理的两大核心痛点痛点1&#xff1a;特征依赖人工设计&#xff0c;通用性差痛点2&#xff1a;全连接网络参数爆炸&#xff0c;训练难收敛二.CNN的核心原理&#xff1a;两大机制与分层感知逻辑1.核心机制1&#xff1a;局部连接&…

用 SPL 编写阿里云 FC2.0 函数

前言 在数字化转型持续加速的背景下&#xff0c;企业越来越多地将业务逻辑以服务化方式部署至云端。阿里云函数计算&#xff08;Function Compute&#xff0c;简称FC&#xff09;作为一种无服务器计算平台&#xff0c;屏蔽了底层资源运维的复杂性&#xff0c;使开发者能够专注…

AR 巡检与普通巡检有哪些区别,有哪些优势|阿法龙XR云平台

AR 巡检&#xff08;增强现实巡检&#xff09;与普通巡检&#xff08;传统人工巡检&#xff09;在技术应用、效率、准确性等多个维度存在显著差异&#xff0c;具体区别如下&#xff1a; 1. 巡检方式更智能 普通巡检&#xff1a;依赖人工现场观察&#xff0c;主要通过眼看、手…

Java中的volatile关键字详解

核心作用&#xff1a;解决可见性和有序性问题volatile 的主要作用可以归结为两点&#xff1a;1.保证变量的可见性 和 禁止指令重排序。2.它提供了一种轻量级的同步机制&#xff0c;3.但需要注意的是&#xff0c;它不能保证原子性。保证可见性&#xff1a;什么是可见性问题&…

【Linux】MySQL数据目录迁移步骤(含流程图踩坑经验)

在生产环境中&#xff0c;有时候你会遇到一些看似简单但实际上很棘手的问题。最近我就碰到了一次典型的服务器磁盘空间告急&#xff0c;最后通过迁移 MySQL 数据目录成功解决了问题。本文记录整个过程&#xff0c;包括我的分析思路、迁移步骤、踩坑和经验总结&#xff0c;希望对…

数据驱动下的连锁模式复制:技术科普与方法论深度解析

前言在连锁经营的赛道上&#xff0c;“复制”是核心命题&#xff0c;但绝非简单的“粘贴”。当行业进入数字化深水区&#xff0c;数据驱动正成为连锁模式突破增长瓶颈、实现高效复制的“隐形引擎”。本文将从技术科普与方法论心得两个维度&#xff0c;深度拆解数据如何重塑连锁…

数据库学习MySQL系列2、Windows11系统安装MySQL方法一.msi安装详细教程

方法一.msi安装详细教程 Windows系统下MySQL——.msi安装详细教程&#xff08;默认--只安装服务端“Server only”&#xff09;MySql官网地址&#xff1a;https://www.mysql.com/&#xff1b;快速下载通道请单击→ No thanks, just start my download.ps&#xff1a;其他资源(…

html+css+vue实现增删改查

代码如下&#xff1a;<!DOCTYPE html> <html lang"zh-CN"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>优化版 Vue.js CRUD 示例&l…

(计算机网络)DNS解析流程及两种途径

在计算机网络中&#xff0c;DNS&#xff08;Domain Name System&#xff09;用于 将域名解析为 IP 地址。一个完整的解析过程涉及 递归查询、迭代查询&#xff0c;以及多个关键角色&#xff08;LDNS、本地域名服务器&#xff1b;根服务器&#xff1b;顶级域名服务器&#xff1b…

数据结构——队列(Java)

一.基本概念 队列用来存储逻辑关系为“一对一”的数据&#xff0c;是一种“特殊”的线性存储结构。 特点&#xff1a; •先进先出&#xff1a;队列中元素的添加&#xff08;入队enqueue&#xff09;和移除&#xff08;出队dequeue&#xff09;遵循先进先出的原 则。 •端点&…

【Go】:mac 环境下GoFrame安装开发工具 gf-cli——gf_darwin_arm64

当前主要是关于gf_darwin_arm64的安装步骤 如何快速给mac电脑安装gfgf是什么安装步骤方法1&#xff1a;去github下载gf-cli去git上下载对应电脑版本的gf-cli验证下载文件是否二进制文件授予该文件权限方法2&#xff1a;去goframe官网教你下载步骤验证gf是否安装成功可能遇到的问…

【新】ApiHug官方文档-ApiHug Spring Security 扩展-补充说明

概述 在上次说明中我们写了ApiHug 如何做授权的&#xff0c; 这里有个概念的混淆&#xff0c; 其实 apihug 不是在spring security 上做的安全扩展&#xff0c; 应该是 apihug spring, 安全设计框架&#xff0c; 和本身 spring security 没有半毛钱关系&#xff0c; 而如果你…

【Flask】测试平台开发,新增说明书编写和展示功能 第二十三篇

概述&#xff1a;本篇是接着上一篇&#xff0c;细分出说明书的编写部分&#xff0c;实现这个功能的需求&#xff0c;是内部很多同事反馈&#xff0c;需要有个地方存工具&#xff0c;并且可以写说明书&#xff0c;如果需要的人&#xff0c;那么可以在界面上直接下载工具和查看工…