Lint vertical spacing in the code (#3224)
* Lint vertical spacing in the code * Add some vertical spacing for readability
This commit is contained in:
parent
83c18498e9
commit
d568d9f5d0
|
|
@ -1,6 +1,6 @@
|
|||
on: [push, pull_request]
|
||||
|
||||
name: CI
|
||||
name: Rust
|
||||
|
||||
env:
|
||||
# web_sys_unstable_apis is required to enable the web_sys clipboard API which eframe web uses,
|
||||
|
|
@ -37,6 +37,9 @@ jobs:
|
|||
- name: Rustfmt
|
||||
run: cargo fmt --all -- --check
|
||||
|
||||
- name: Lint vertical spacing
|
||||
run: ./scripts/lint.py
|
||||
|
||||
- name: Install cargo-cranky
|
||||
uses: baptiste0928/cargo-install@v1
|
||||
with:
|
||||
|
|
@ -145,7 +148,7 @@ jobs:
|
|||
rust-version: "1.65.0"
|
||||
log-level: error
|
||||
command: check
|
||||
arguments: ${{ matrix.flags }} --target ${{ matrix.target }}
|
||||
arguments: --target ${{ matrix.target }}
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
|
|
|
|||
|
|
@ -60,7 +60,7 @@ Read the section on integrations at <https://github.com/emilk/egui#integrations>
|
|||
## Code Conventions
|
||||
Conventions unless otherwise specified:
|
||||
|
||||
* angles are in radians
|
||||
* angles are in radians and clock-wise
|
||||
* `Vec2::X` is right and `Vec2::Y` is down.
|
||||
* `Pos2::ZERO` is left top.
|
||||
|
||||
|
|
|
|||
|
|
@ -272,6 +272,7 @@ pub fn run_simple_native(
|
|||
struct SimpleApp<U> {
|
||||
update_fun: U,
|
||||
}
|
||||
|
||||
impl<U: FnMut(&egui::Context, &mut Frame)> App for SimpleApp<U> {
|
||||
fn update(&mut self, ctx: &egui::Context, frame: &mut Frame) {
|
||||
(self.update_fun)(ctx, frame);
|
||||
|
|
|
|||
|
|
@ -335,8 +335,10 @@ pub struct EpiIntegration {
|
|||
pub egui_ctx: egui::Context,
|
||||
pending_full_output: egui::FullOutput,
|
||||
egui_winit: egui_winit::State,
|
||||
|
||||
/// When set, it is time to close the native window.
|
||||
close: bool,
|
||||
|
||||
can_drag_window: bool,
|
||||
window_state: WindowState,
|
||||
follow_system_theme: bool,
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@ use super::epi_integration::{self, EpiIntegration};
|
|||
pub enum UserEvent {
|
||||
RequestRepaint {
|
||||
when: Instant,
|
||||
|
||||
/// What the frame number was when the repaint was _requested_.
|
||||
frame_nr: u64,
|
||||
},
|
||||
|
|
|
|||
|
|
@ -334,16 +334,22 @@ struct Prepared {
|
|||
state: State,
|
||||
has_bar: [bool; 2],
|
||||
auto_shrink: [bool; 2],
|
||||
|
||||
/// How much horizontal and vertical space are used up by the
|
||||
/// width of the vertical bar, and the height of the horizontal bar?
|
||||
current_bar_use: Vec2,
|
||||
|
||||
scroll_bar_visibility: ScrollBarVisibility,
|
||||
|
||||
/// Where on the screen the content is (excludes scroll bars).
|
||||
inner_rect: Rect,
|
||||
|
||||
content_ui: Ui,
|
||||
|
||||
/// Relative coordinates: the offset and size of the view of the inner UI.
|
||||
/// `viewport.min == ZERO` means we scrolled to the top.
|
||||
viewport: Rect,
|
||||
|
||||
scrolling_enabled: bool,
|
||||
stick_to_end: [bool; 2],
|
||||
}
|
||||
|
|
|
|||
|
|
@ -693,27 +693,37 @@ pub enum Key {
|
|||
|
||||
/// The virtual keycode for the Minus key.
|
||||
Minus,
|
||||
|
||||
/// The virtual keycode for the Plus/Equals key.
|
||||
PlusEquals,
|
||||
|
||||
/// Either from the main row or from the numpad.
|
||||
Num0,
|
||||
|
||||
/// Either from the main row or from the numpad.
|
||||
Num1,
|
||||
|
||||
/// Either from the main row or from the numpad.
|
||||
Num2,
|
||||
|
||||
/// Either from the main row or from the numpad.
|
||||
Num3,
|
||||
|
||||
/// Either from the main row or from the numpad.
|
||||
Num4,
|
||||
|
||||
/// Either from the main row or from the numpad.
|
||||
Num5,
|
||||
|
||||
/// Either from the main row or from the numpad.
|
||||
Num6,
|
||||
|
||||
/// Either from the main row or from the numpad.
|
||||
Num7,
|
||||
|
||||
/// Either from the main row or from the numpad.
|
||||
Num8,
|
||||
|
||||
/// Either from the main row or from the numpad.
|
||||
Num9,
|
||||
|
||||
|
|
|
|||
|
|
@ -60,6 +60,7 @@ pub(crate) struct GridLayout {
|
|||
/// State previous frame (if any).
|
||||
/// This can be used to predict future sizes of cells.
|
||||
prev_state: State,
|
||||
|
||||
/// State accumulated during the current frame.
|
||||
curr_state: State,
|
||||
initial_available: Rect,
|
||||
|
|
|
|||
|
|
@ -546,8 +546,10 @@ impl Memory {
|
|||
#[cfg_attr(feature = "serde", serde(default))]
|
||||
pub struct Areas {
|
||||
areas: IdMap<area::State>,
|
||||
|
||||
/// Back-to-front. Top is last.
|
||||
order: Vec<LayerId>,
|
||||
|
||||
visible_last_frame: ahash::HashSet<LayerId>,
|
||||
visible_current_frame: ahash::HashSet<LayerId>,
|
||||
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@ pub struct Button {
|
|||
text: WidgetText,
|
||||
shortcut_text: WidgetText,
|
||||
wrap: Option<bool>,
|
||||
|
||||
/// None means default for interact
|
||||
fill: Option<Color32>,
|
||||
stroke: Option<Stroke>,
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ use crate::*;
|
|||
pub(crate) struct MonoState {
|
||||
last_dragged_id: Option<Id>,
|
||||
last_dragged_value: Option<f64>,
|
||||
|
||||
/// For temporary edit of a [`DragValue`] value.
|
||||
/// Couples with the current focus id.
|
||||
edit_string: Option<String>,
|
||||
|
|
|
|||
|
|
@ -760,15 +760,22 @@ impl PlotItem for Text {
|
|||
/// A set of points.
|
||||
pub struct Points {
|
||||
pub(super) series: PlotPoints,
|
||||
|
||||
pub(super) shape: MarkerShape,
|
||||
|
||||
/// Color of the marker. `Color32::TRANSPARENT` means that it will be picked automatically.
|
||||
pub(super) color: Color32,
|
||||
|
||||
/// Whether to fill the marker. Does not apply to all types.
|
||||
pub(super) filled: bool,
|
||||
|
||||
/// The maximum extent of the marker from its center.
|
||||
pub(super) radius: f32,
|
||||
|
||||
pub(super) name: String,
|
||||
|
||||
pub(super) highlight: bool,
|
||||
|
||||
pub(super) stems: Option<f32>,
|
||||
}
|
||||
|
||||
|
|
@ -1290,8 +1297,10 @@ pub struct BarChart {
|
|||
pub(super) bars: Vec<Bar>,
|
||||
pub(super) default_color: Color32,
|
||||
pub(super) name: String,
|
||||
|
||||
/// A custom element formatter
|
||||
pub(super) element_formatter: Option<Box<dyn Fn(&Bar, &BarChart) -> String>>,
|
||||
|
||||
highlight: bool,
|
||||
}
|
||||
|
||||
|
|
@ -1460,8 +1469,10 @@ pub struct BoxPlot {
|
|||
pub(super) boxes: Vec<BoxElem>,
|
||||
pub(super) default_color: Color32,
|
||||
pub(super) name: String,
|
||||
|
||||
/// A custom element formatter
|
||||
pub(super) element_formatter: Option<Box<dyn Fn(&BoxElem, &BoxPlot) -> String>>,
|
||||
|
||||
highlight: bool,
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -101,9 +101,11 @@ struct PlotMemory {
|
|||
/// 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.
|
||||
bounds_modified: AxisBools,
|
||||
|
||||
hovered_entry: Option<String>,
|
||||
hidden_items: ahash::HashSet<String>,
|
||||
last_plot_transform: PlotTransform,
|
||||
|
||||
/// Allows to remember the first click position when performing a boxed zoom
|
||||
last_click_pos_for_zoom: Option<Pos2>,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -77,8 +77,10 @@ pub struct Slider<'a> {
|
|||
prefix: String,
|
||||
suffix: String,
|
||||
text: WidgetText,
|
||||
|
||||
/// Sets the minimal step of the widget value
|
||||
step: Option<f64>,
|
||||
|
||||
drag_value_speed: Option<f64>,
|
||||
min_decimals: usize,
|
||||
max_decimals: Option<usize>,
|
||||
|
|
|
|||
|
|
@ -10,11 +10,15 @@ pub use usvg::FitTo;
|
|||
/// Use the `svg` and `image` features to enable more constructors.
|
||||
pub struct RetainedImage {
|
||||
debug_name: String,
|
||||
|
||||
size: [usize; 2],
|
||||
|
||||
/// Cleared once [`Self::texture`] has been loaded.
|
||||
image: Mutex<egui::ColorImage>,
|
||||
|
||||
/// Lazily loaded when we have an egui context.
|
||||
texture: Mutex<Option<egui::TextureHandle>>,
|
||||
|
||||
options: TextureOptions,
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -32,9 +32,11 @@ pub struct StripLayout<'l> {
|
|||
direction: CellDirection,
|
||||
pub(crate) rect: Rect,
|
||||
pub(crate) cursor: Pos2,
|
||||
|
||||
/// Keeps track of the max used position,
|
||||
/// so we know how much space we used.
|
||||
max: Pos2,
|
||||
|
||||
cell_layout: egui::Layout,
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -28,7 +28,9 @@ enum InitialColumnSize {
|
|||
#[derive(Clone, Copy, Debug, PartialEq)]
|
||||
pub struct Column {
|
||||
initial_width: InitialColumnSize,
|
||||
|
||||
width_range: Rangef,
|
||||
|
||||
/// Clip contents if too narrow?
|
||||
clip: bool,
|
||||
|
||||
|
|
@ -511,8 +513,10 @@ pub struct Table<'a> {
|
|||
columns: Vec<Column>,
|
||||
available_width: f32,
|
||||
state: TableState,
|
||||
|
||||
/// Accumulated maximum used widths for each column.
|
||||
max_used_widths: Vec<f32>,
|
||||
|
||||
first_frame_auto_size_columns: bool,
|
||||
resizable: bool,
|
||||
striped: bool,
|
||||
|
|
@ -1011,8 +1015,10 @@ pub struct TableRow<'a, 'b> {
|
|||
layout: &'b mut StripLayout<'a>,
|
||||
columns: &'b [Column],
|
||||
widths: &'b [f32],
|
||||
|
||||
/// grows during building with the maximum widths
|
||||
max_used_widths: &'b mut [f32],
|
||||
|
||||
col_index: usize,
|
||||
striped: bool,
|
||||
height: f32,
|
||||
|
|
|
|||
|
|
@ -13,17 +13,15 @@ use emath::*;
|
|||
|
||||
#[allow(clippy::approx_constant)]
|
||||
mod precomputed_vertices {
|
||||
/*
|
||||
fn main() {
|
||||
let n = 64;
|
||||
println!("pub const CIRCLE_{}: [Vec2; {}] = [", n, n+1);
|
||||
for i in 0..=n {
|
||||
let a = std::f64::consts::TAU * i as f64 / n as f64;
|
||||
println!(" vec2({:.06}, {:.06}),", a.cos(), a.sin());
|
||||
}
|
||||
println!("];")
|
||||
}
|
||||
*/
|
||||
// fn main() {
|
||||
// let n = 64;
|
||||
// println!("pub const CIRCLE_{}: [Vec2; {}] = [", n, n+1);
|
||||
// for i in 0..=n {
|
||||
// let a = std::f64::consts::TAU * i as f64 / n as f64;
|
||||
// println!(" vec2({:.06}, {:.06}),", a.cos(), a.sin());
|
||||
// }
|
||||
// println!("];")
|
||||
// }
|
||||
|
||||
use emath::{vec2, Vec2};
|
||||
|
||||
|
|
|
|||
|
|
@ -78,11 +78,15 @@ impl Default for GlyphInfo {
|
|||
pub struct FontImpl {
|
||||
name: String,
|
||||
ab_glyph_font: ab_glyph::FontArc,
|
||||
|
||||
/// Maximum character height
|
||||
scale_in_pixels: u32,
|
||||
|
||||
height_in_points: f32,
|
||||
|
||||
// move each character by this much (hack)
|
||||
y_offset: f32,
|
||||
|
||||
ascent: f32,
|
||||
pixels_per_point: f32,
|
||||
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)
|
||||
pub struct Font {
|
||||
fonts: Vec<Arc<FontImpl>>,
|
||||
|
||||
/// Lazily calculated.
|
||||
characters: Option<BTreeSet<char>>,
|
||||
|
||||
replacement_glyph: (FontIndex, GlyphInfo),
|
||||
pixels_per_point: f32,
|
||||
row_height: f32,
|
||||
|
|
|
|||
|
|
@ -193,8 +193,10 @@ impl std::hash::Hash for LayoutJob {
|
|||
pub struct LayoutSection {
|
||||
/// Can be used for first row indentation.
|
||||
pub leading_space: f32,
|
||||
|
||||
/// Range into the galley text
|
||||
pub byte_range: Range<usize>,
|
||||
|
||||
pub format: TextFormat,
|
||||
}
|
||||
|
||||
|
|
@ -218,12 +220,18 @@ impl std::hash::Hash for LayoutSection {
|
|||
#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
|
||||
pub struct TextFormat {
|
||||
pub font_id: FontId,
|
||||
|
||||
/// Text color
|
||||
pub color: Color32,
|
||||
|
||||
pub background: Color32,
|
||||
|
||||
pub italics: bool,
|
||||
|
||||
pub underline: Stroke,
|
||||
|
||||
pub strikethrough: Stroke,
|
||||
|
||||
/// If you use a small font and [`Align::TOP`] you
|
||||
/// can get the effect of raised text.
|
||||
pub valign: Align,
|
||||
|
|
|
|||
|
|
@ -9,8 +9,10 @@ use crate::{ImageData, ImageDelta, TextureId};
|
|||
pub struct TextureManager {
|
||||
/// We allocate texture id:s linearly.
|
||||
next_id: u64,
|
||||
|
||||
/// Information about currently allocated textures.
|
||||
metas: ahash::HashMap<TextureId, TextureMeta>,
|
||||
|
||||
delta: TexturesDelta,
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
Loading…
Reference in New Issue