Lint vertical spacing in the code (#3224)

* Lint vertical spacing in the code

* Add some vertical spacing for readability
This commit is contained in:
Emil Ernerfeldt 2023-08-10 15:26:54 +02:00 committed by GitHub
parent 83c18498e9
commit d568d9f5d0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
22 changed files with 215 additions and 14 deletions

View File

@ -1,6 +1,6 @@
on: [push, pull_request] on: [push, pull_request]
name: CI name: Rust
env: env:
# web_sys_unstable_apis is required to enable the web_sys clipboard API which eframe web uses, # web_sys_unstable_apis is required to enable the web_sys clipboard API which eframe web uses,
@ -37,6 +37,9 @@ jobs:
- name: Rustfmt - name: Rustfmt
run: cargo fmt --all -- --check run: cargo fmt --all -- --check
- name: Lint vertical spacing
run: ./scripts/lint.py
- name: Install cargo-cranky - name: Install cargo-cranky
uses: baptiste0928/cargo-install@v1 uses: baptiste0928/cargo-install@v1
with: with:
@ -145,7 +148,7 @@ jobs:
rust-version: "1.65.0" rust-version: "1.65.0"
log-level: error log-level: error
command: check command: check
arguments: ${{ matrix.flags }} --target ${{ matrix.target }} arguments: --target ${{ matrix.target }}
# --------------------------------------------------------------------------- # ---------------------------------------------------------------------------

View File

@ -60,7 +60,7 @@ Read the section on integrations at <https://github.com/emilk/egui#integrations>
## Code Conventions ## Code Conventions
Conventions unless otherwise specified: Conventions unless otherwise specified:
* angles are in radians * angles are in radians and clock-wise
* `Vec2::X` is right and `Vec2::Y` is down. * `Vec2::X` is right and `Vec2::Y` is down.
* `Pos2::ZERO` is left top. * `Pos2::ZERO` is left top.

View File

@ -272,6 +272,7 @@ pub fn run_simple_native(
struct SimpleApp<U> { struct SimpleApp<U> {
update_fun: U, update_fun: U,
} }
impl<U: FnMut(&egui::Context, &mut Frame)> App for SimpleApp<U> { impl<U: FnMut(&egui::Context, &mut Frame)> App for SimpleApp<U> {
fn update(&mut self, ctx: &egui::Context, frame: &mut Frame) { fn update(&mut self, ctx: &egui::Context, frame: &mut Frame) {
(self.update_fun)(ctx, frame); (self.update_fun)(ctx, frame);

View File

@ -335,8 +335,10 @@ pub struct EpiIntegration {
pub egui_ctx: egui::Context, pub egui_ctx: egui::Context,
pending_full_output: egui::FullOutput, pending_full_output: egui::FullOutput,
egui_winit: egui_winit::State, egui_winit: egui_winit::State,
/// When set, it is time to close the native window. /// When set, it is time to close the native window.
close: bool, close: bool,
can_drag_window: bool, can_drag_window: bool,
window_state: WindowState, window_state: WindowState,
follow_system_theme: bool, follow_system_theme: bool,

View File

@ -22,6 +22,7 @@ use super::epi_integration::{self, EpiIntegration};
pub enum UserEvent { pub enum UserEvent {
RequestRepaint { RequestRepaint {
when: Instant, when: Instant,
/// What the frame number was when the repaint was _requested_. /// What the frame number was when the repaint was _requested_.
frame_nr: u64, frame_nr: u64,
}, },

View File

@ -334,16 +334,22 @@ struct Prepared {
state: State, state: State,
has_bar: [bool; 2], has_bar: [bool; 2],
auto_shrink: [bool; 2], auto_shrink: [bool; 2],
/// How much horizontal and vertical space are used up by the /// How much horizontal and vertical space are used up by the
/// width of the vertical bar, and the height of the horizontal bar? /// width of the vertical bar, and the height of the horizontal bar?
current_bar_use: Vec2, current_bar_use: Vec2,
scroll_bar_visibility: ScrollBarVisibility, scroll_bar_visibility: ScrollBarVisibility,
/// Where on the screen the content is (excludes scroll bars). /// Where on the screen the content is (excludes scroll bars).
inner_rect: Rect, inner_rect: Rect,
content_ui: Ui, content_ui: Ui,
/// Relative coordinates: the offset and size of the view of the inner UI. /// Relative coordinates: the offset and size of the view of the inner UI.
/// `viewport.min == ZERO` means we scrolled to the top. /// `viewport.min == ZERO` means we scrolled to the top.
viewport: Rect, viewport: Rect,
scrolling_enabled: bool, scrolling_enabled: bool,
stick_to_end: [bool; 2], stick_to_end: [bool; 2],
} }

View File

@ -693,27 +693,37 @@ pub enum Key {
/// The virtual keycode for the Minus key. /// The virtual keycode for the Minus key.
Minus, Minus,
/// The virtual keycode for the Plus/Equals key. /// The virtual keycode for the Plus/Equals key.
PlusEquals, PlusEquals,
/// Either from the main row or from the numpad. /// Either from the main row or from the numpad.
Num0, Num0,
/// Either from the main row or from the numpad. /// Either from the main row or from the numpad.
Num1, Num1,
/// Either from the main row or from the numpad. /// Either from the main row or from the numpad.
Num2, Num2,
/// Either from the main row or from the numpad. /// Either from the main row or from the numpad.
Num3, Num3,
/// Either from the main row or from the numpad. /// Either from the main row or from the numpad.
Num4, Num4,
/// Either from the main row or from the numpad. /// Either from the main row or from the numpad.
Num5, Num5,
/// Either from the main row or from the numpad. /// Either from the main row or from the numpad.
Num6, Num6,
/// Either from the main row or from the numpad. /// Either from the main row or from the numpad.
Num7, Num7,
/// Either from the main row or from the numpad. /// Either from the main row or from the numpad.
Num8, Num8,
/// Either from the main row or from the numpad. /// Either from the main row or from the numpad.
Num9, Num9,

View File

@ -60,6 +60,7 @@ pub(crate) struct GridLayout {
/// State previous frame (if any). /// State previous frame (if any).
/// This can be used to predict future sizes of cells. /// This can be used to predict future sizes of cells.
prev_state: State, prev_state: State,
/// State accumulated during the current frame. /// State accumulated during the current frame.
curr_state: State, curr_state: State,
initial_available: Rect, initial_available: Rect,

View File

@ -546,8 +546,10 @@ impl Memory {
#[cfg_attr(feature = "serde", serde(default))] #[cfg_attr(feature = "serde", serde(default))]
pub struct Areas { pub struct Areas {
areas: IdMap<area::State>, areas: IdMap<area::State>,
/// Back-to-front. Top is last. /// Back-to-front. Top is last.
order: Vec<LayerId>, order: Vec<LayerId>,
visible_last_frame: ahash::HashSet<LayerId>, visible_last_frame: ahash::HashSet<LayerId>,
visible_current_frame: ahash::HashSet<LayerId>, visible_current_frame: ahash::HashSet<LayerId>,

View File

@ -23,6 +23,7 @@ pub struct Button {
text: WidgetText, text: WidgetText,
shortcut_text: WidgetText, shortcut_text: WidgetText,
wrap: Option<bool>, wrap: Option<bool>,
/// None means default for interact /// None means default for interact
fill: Option<Color32>, fill: Option<Color32>,
stroke: Option<Stroke>, stroke: Option<Stroke>,

View File

@ -11,6 +11,7 @@ use crate::*;
pub(crate) struct MonoState { pub(crate) struct MonoState {
last_dragged_id: Option<Id>, last_dragged_id: Option<Id>,
last_dragged_value: Option<f64>, last_dragged_value: Option<f64>,
/// For temporary edit of a [`DragValue`] value. /// For temporary edit of a [`DragValue`] value.
/// Couples with the current focus id. /// Couples with the current focus id.
edit_string: Option<String>, edit_string: Option<String>,

View File

@ -760,15 +760,22 @@ impl PlotItem for Text {
/// A set of points. /// A set of points.
pub struct Points { pub struct Points {
pub(super) series: PlotPoints, pub(super) series: PlotPoints,
pub(super) shape: MarkerShape, pub(super) shape: MarkerShape,
/// Color of the marker. `Color32::TRANSPARENT` means that it will be picked automatically. /// Color of the marker. `Color32::TRANSPARENT` means that it will be picked automatically.
pub(super) color: Color32, pub(super) color: Color32,
/// Whether to fill the marker. Does not apply to all types. /// Whether to fill the marker. Does not apply to all types.
pub(super) filled: bool, pub(super) filled: bool,
/// The maximum extent of the marker from its center. /// The maximum extent of the marker from its center.
pub(super) radius: f32, pub(super) radius: f32,
pub(super) name: String, pub(super) name: String,
pub(super) highlight: bool, pub(super) highlight: bool,
pub(super) stems: Option<f32>, pub(super) stems: Option<f32>,
} }
@ -1290,8 +1297,10 @@ pub struct BarChart {
pub(super) bars: Vec<Bar>, pub(super) bars: Vec<Bar>,
pub(super) default_color: Color32, pub(super) default_color: Color32,
pub(super) name: String, pub(super) name: String,
/// A custom element formatter /// A custom element formatter
pub(super) element_formatter: Option<Box<dyn Fn(&Bar, &BarChart) -> String>>, pub(super) element_formatter: Option<Box<dyn Fn(&Bar, &BarChart) -> String>>,
highlight: bool, highlight: bool,
} }
@ -1460,8 +1469,10 @@ pub struct BoxPlot {
pub(super) boxes: Vec<BoxElem>, pub(super) boxes: Vec<BoxElem>,
pub(super) default_color: Color32, pub(super) default_color: Color32,
pub(super) name: String, pub(super) name: String,
/// A custom element formatter /// A custom element formatter
pub(super) element_formatter: Option<Box<dyn Fn(&BoxElem, &BoxPlot) -> String>>, pub(super) element_formatter: Option<Box<dyn Fn(&BoxElem, &BoxPlot) -> String>>,
highlight: bool, highlight: bool,
} }

View File

@ -101,9 +101,11 @@ struct PlotMemory {
/// Indicates if the user has modified the bounds, for example by moving or zooming, /// Indicates if the user has modified the bounds, for example by moving or zooming,
/// or if the bounds should be calculated based by included point or auto bounds. /// or if the bounds should be calculated based by included point or auto bounds.
bounds_modified: AxisBools, bounds_modified: AxisBools,
hovered_entry: Option<String>, hovered_entry: Option<String>,
hidden_items: ahash::HashSet<String>, hidden_items: ahash::HashSet<String>,
last_plot_transform: PlotTransform, last_plot_transform: PlotTransform,
/// Allows to remember the first click position when performing a boxed zoom /// Allows to remember the first click position when performing a boxed zoom
last_click_pos_for_zoom: Option<Pos2>, last_click_pos_for_zoom: Option<Pos2>,
} }

View File

@ -77,8 +77,10 @@ pub struct Slider<'a> {
prefix: String, prefix: String,
suffix: String, suffix: String,
text: WidgetText, text: WidgetText,
/// Sets the minimal step of the widget value /// Sets the minimal step of the widget value
step: Option<f64>, step: Option<f64>,
drag_value_speed: Option<f64>, drag_value_speed: Option<f64>,
min_decimals: usize, min_decimals: usize,
max_decimals: Option<usize>, max_decimals: Option<usize>,

View File

@ -10,11 +10,15 @@ pub use usvg::FitTo;
/// Use the `svg` and `image` features to enable more constructors. /// Use the `svg` and `image` features to enable more constructors.
pub struct RetainedImage { pub struct RetainedImage {
debug_name: String, debug_name: String,
size: [usize; 2], size: [usize; 2],
/// Cleared once [`Self::texture`] has been loaded. /// Cleared once [`Self::texture`] has been loaded.
image: Mutex<egui::ColorImage>, image: Mutex<egui::ColorImage>,
/// Lazily loaded when we have an egui context. /// Lazily loaded when we have an egui context.
texture: Mutex<Option<egui::TextureHandle>>, texture: Mutex<Option<egui::TextureHandle>>,
options: TextureOptions, options: TextureOptions,
} }

View File

@ -32,9 +32,11 @@ pub struct StripLayout<'l> {
direction: CellDirection, direction: CellDirection,
pub(crate) rect: Rect, pub(crate) rect: Rect,
pub(crate) cursor: Pos2, pub(crate) cursor: Pos2,
/// Keeps track of the max used position, /// Keeps track of the max used position,
/// so we know how much space we used. /// so we know how much space we used.
max: Pos2, max: Pos2,
cell_layout: egui::Layout, cell_layout: egui::Layout,
} }

View File

@ -28,7 +28,9 @@ enum InitialColumnSize {
#[derive(Clone, Copy, Debug, PartialEq)] #[derive(Clone, Copy, Debug, PartialEq)]
pub struct Column { pub struct Column {
initial_width: InitialColumnSize, initial_width: InitialColumnSize,
width_range: Rangef, width_range: Rangef,
/// Clip contents if too narrow? /// Clip contents if too narrow?
clip: bool, clip: bool,
@ -511,8 +513,10 @@ pub struct Table<'a> {
columns: Vec<Column>, columns: Vec<Column>,
available_width: f32, available_width: f32,
state: TableState, state: TableState,
/// Accumulated maximum used widths for each column. /// Accumulated maximum used widths for each column.
max_used_widths: Vec<f32>, max_used_widths: Vec<f32>,
first_frame_auto_size_columns: bool, first_frame_auto_size_columns: bool,
resizable: bool, resizable: bool,
striped: bool, striped: bool,
@ -1011,8 +1015,10 @@ pub struct TableRow<'a, 'b> {
layout: &'b mut StripLayout<'a>, layout: &'b mut StripLayout<'a>,
columns: &'b [Column], columns: &'b [Column],
widths: &'b [f32], widths: &'b [f32],
/// grows during building with the maximum widths /// grows during building with the maximum widths
max_used_widths: &'b mut [f32], max_used_widths: &'b mut [f32],
col_index: usize, col_index: usize,
striped: bool, striped: bool,
height: f32, height: f32,

View File

@ -13,17 +13,15 @@ use emath::*;
#[allow(clippy::approx_constant)] #[allow(clippy::approx_constant)]
mod precomputed_vertices { mod precomputed_vertices {
/* // fn main() {
fn main() { // let n = 64;
let n = 64; // println!("pub const CIRCLE_{}: [Vec2; {}] = [", n, n+1);
println!("pub const CIRCLE_{}: [Vec2; {}] = [", n, n+1); // for i in 0..=n {
for i in 0..=n { // let a = std::f64::consts::TAU * i as f64 / n as f64;
let a = std::f64::consts::TAU * i as f64 / n as f64; // println!(" vec2({:.06}, {:.06}),", a.cos(), a.sin());
println!(" vec2({:.06}, {:.06}),", a.cos(), a.sin()); // }
} // println!("];")
println!("];") // }
}
*/
use emath::{vec2, Vec2}; use emath::{vec2, Vec2};

View File

@ -78,11 +78,15 @@ impl Default for GlyphInfo {
pub struct FontImpl { pub struct FontImpl {
name: String, name: String,
ab_glyph_font: ab_glyph::FontArc, ab_glyph_font: ab_glyph::FontArc,
/// Maximum character height /// Maximum character height
scale_in_pixels: u32, scale_in_pixels: u32,
height_in_points: f32, height_in_points: f32,
// move each character by this much (hack) // move each character by this much (hack)
y_offset: f32, y_offset: f32,
ascent: f32, ascent: f32,
pixels_per_point: f32, pixels_per_point: f32,
glyph_info_cache: RwLock<ahash::HashMap<char, GlyphInfo>>, // TODO(emilk): standard Mutex glyph_info_cache: RwLock<ahash::HashMap<char, GlyphInfo>>, // TODO(emilk): standard Mutex
@ -320,8 +324,10 @@ type FontIndex = usize;
/// Wrapper over multiple [`FontImpl`] (e.g. a primary + fallbacks for emojis) /// Wrapper over multiple [`FontImpl`] (e.g. a primary + fallbacks for emojis)
pub struct Font { pub struct Font {
fonts: Vec<Arc<FontImpl>>, fonts: Vec<Arc<FontImpl>>,
/// Lazily calculated. /// Lazily calculated.
characters: Option<BTreeSet<char>>, characters: Option<BTreeSet<char>>,
replacement_glyph: (FontIndex, GlyphInfo), replacement_glyph: (FontIndex, GlyphInfo),
pixels_per_point: f32, pixels_per_point: f32,
row_height: f32, row_height: f32,

View File

@ -193,8 +193,10 @@ impl std::hash::Hash for LayoutJob {
pub struct LayoutSection { pub struct LayoutSection {
/// Can be used for first row indentation. /// Can be used for first row indentation.
pub leading_space: f32, pub leading_space: f32,
/// Range into the galley text /// Range into the galley text
pub byte_range: Range<usize>, pub byte_range: Range<usize>,
pub format: TextFormat, pub format: TextFormat,
} }
@ -218,12 +220,18 @@ impl std::hash::Hash for LayoutSection {
#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))] #[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
pub struct TextFormat { pub struct TextFormat {
pub font_id: FontId, pub font_id: FontId,
/// Text color /// Text color
pub color: Color32, pub color: Color32,
pub background: Color32, pub background: Color32,
pub italics: bool, pub italics: bool,
pub underline: Stroke, pub underline: Stroke,
pub strikethrough: Stroke, pub strikethrough: Stroke,
/// If you use a small font and [`Align::TOP`] you /// If you use a small font and [`Align::TOP`] you
/// can get the effect of raised text. /// can get the effect of raised text.
pub valign: Align, pub valign: Align,

View File

@ -9,8 +9,10 @@ use crate::{ImageData, ImageDelta, TextureId};
pub struct TextureManager { pub struct TextureManager {
/// We allocate texture id:s linearly. /// We allocate texture id:s linearly.
next_id: u64, next_id: u64,
/// Information about currently allocated textures. /// Information about currently allocated textures.
metas: ahash::HashMap<TextureId, TextureMeta>, metas: ahash::HashMap<TextureId, TextureMeta>,
delta: TexturesDelta, delta: TexturesDelta,
} }

132
scripts/lint.py Executable file
View File

@ -0,0 +1,132 @@
#!/usr/bin/env python
"""
Runs custom linting on Rust code.
"""
import argparse
import os
import re
import sys
def lint_file_path(filepath, args) -> int:
with open(filepath) as f:
lines_in = f.readlines()
errors, lines_out = lint_lines(filepath, lines_in)
for error in errors:
print(error)
if args.fix and lines_in != lines_out:
with open(filepath, 'w') as f:
f.writelines(lines_out)
print(f'{filepath} fixed.')
return len(errors)
def lint_lines(filepath, lines_in):
last_line_was_empty = True
errors = []
lines_out = []
for line_nr, line in enumerate(lines_in):
line_nr = line_nr+1
# TODO: only # and /// on lines before a keyword
pattern = r'^\s*((///)|((pub(\(\w*\))? )?((impl|fn|struct|enum|union|trait)\b))).*$'
if re.match(pattern, line):
if not last_line_was_empty:
errors.append(
f'{filepath}:{line_nr}: for readability, add newline before `{line.strip()}`')
lines_out.append("\n")
lines_out.append(line)
stripped = line.strip()
last_line_was_empty = stripped == '' or \
stripped.startswith('#') or \
stripped.startswith('//') or \
stripped.endswith('{') or \
stripped.endswith('(') or \
stripped.endswith('\\') or \
stripped.endswith('r"') or \
stripped.endswith(']')
return errors, lines_out
def test_lint():
should_pass = [
"hello world",
"""
/// docstring
foo
/// docstring
bar
"""
]
should_fail = [
"""
/// docstring
foo
/// docstring
bar
"""
]
for code in should_pass:
errors, _ = lint_lines("test.py", code.split('\n'))
assert len(errors) == 0, f'expected this to pass:\n{code}\ngot: {errors}'
for code in should_fail:
errors, _ = lint_lines("test.py", code.split('\n'))
assert len(errors) > 0, f'expected this to fail:\n{code}'
pass
def main():
test_lint() # Make sure we are bug free before we run!
parser = argparse.ArgumentParser(
description='Lint Rust code with custom linter.')
parser.add_argument('files', metavar='file', type=str, nargs='*',
help='File paths. Empty = all files, recursively.')
parser.add_argument('--fix', dest='fix', action='store_true',
help='Automatically fix the files')
args = parser.parse_args()
num_errors = 0
if args.files:
for filepath in args.files:
num_errors += lint_file_path(filepath, args)
else:
script_dirpath = os.path.dirname(os.path.realpath(__file__))
root_dirpath = os.path.abspath(f'{script_dirpath}/..')
os.chdir(root_dirpath)
exclude = set(['target', 'target_ra'])
for root, dirs, files in os.walk('.', topdown=True):
dirs[:] = [d for d in dirs if d not in exclude]
for filename in files:
if filename.endswith('.rs'):
filepath = os.path.join(root, filename)
num_errors += lint_file_path(filepath, args)
if num_errors == 0:
print(f"{sys.argv[0]} finished without error")
sys.exit(0)
else:
print(f"{sys.argv[0]} found {num_errors} errors.")
sys.exit(1)
if __name__ == '__main__':
main()