diff --git a/NEWS.md b/NEWS.md index 412ba69..d4a427c 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,15 +1,15 @@ -# v0.5.0-alpha +# v0.5.0 -Version v0.5.0 will be a major release, including breaking changes and substantial new features. I would be very grateful for any help with testing, along with any comments, questions or suggestions, to ensure as much functionality as possible in v0.5.0. Please work from the `main` branch to ensure you have the latest version. +Version v0.5.0 is a major release, including breaking changes and substantial new features. ## Changes to existing CLI options - The option to disable line wrapping has been changed from `--keep` to `--nowrap`. - The option to set the number of characters used per indentation level has been changed from `--tab` to `--tabsize`. - The option to set the maximum line length for wrapping has been changed from `--wrap` to `--wraplen`. -- See below for information on the new `--config`, `--man` and `--completion` flags. +- See below for information on the new `--config`, `--noconfig`, `--man`, `--completion`, and `--args` flags. ## Configuration file support -Configuring tex-fmt can now be achieved using a configuration file as well as CLI arguments. The configuration file can be read from a user-specified path, from the current working directory, from the root of the current git repository, or from the user's configuration directory, in order of decreasing priority. Arguments passed on the command line will always override those specified in configuration files. +Configuring tex-fmt can now be achieved using a configuration file as well as CLI arguments. The configuration file can be read from a user-specified path with `--config`, from the current working directory, from the root of the current git repository, or from the user's configuration directory, in order of decreasing priority. Arguments passed on the command line will always override those specified in configuration files. Configuration files can be disabled by passing `--noconfig`. ## Man pages Man pages can be generated using the `--man` flag. Pre-built man pages are also available for download from the GitHub repository. @@ -18,8 +18,13 @@ Man pages can be generated using the `--man` flag. Pre-built man pages are also Completion files for popular shells, including bash, fish, zsh, elvish and PowerShell, can be generated using the `--completion ` flag. Pre-built completion scripts are also available for download from the GitHub repository. ## Minor changes +- All arguments passed to tex-fmt can be inspected by passing `--args` - Fixed bug with `\itemsep` matching the `\item` pattern - Added last non-indented line number to "Indent did not return to zero" error messages +- Removed LTO optimization to improve compile time with minimal effect on run time +- If duplicate file names are provided, they are now removed before formatting +- Added LLF to the list of existing tools +- Changed order of options in help dialogs # v0.4.7 @@ -33,7 +38,7 @@ Completion files for popular shells, including bash, fish, zsh, elvish and Power # v0.4.6 -- Added ``--wrap`` flag to choose line length for wrapping +- Added `--wrap` flag to choose line length for wrapping - Significant changes to central formatting logic to reduce memory allocations - Treat comment environments as verbatim - Improved performance with finding comments in source code diff --git a/README.md b/README.md index 26590a2..91853a2 100644 --- a/README.md +++ b/README.md @@ -285,17 +285,17 @@ The following command-line options are offered by tex-fmt. | `--check` | `-c` | | Check formatting, do not modify files | | `--print` | `-p` | | Print to stdout, do not modify files | | `--nowrap` | `-n` | | Do not wrap long lines | -| `--verbose` | `-v` | | Show info messages | -| `--quiet` | `-q` | | Hide warning messages | -| `--trace` | | | Show trace messages | -| `--stdin` | `-s` | | Process stdin as a single file, output to stdout | +| `--wraplen` | `-l` | `80` | Line length for wrapping | | `--tabsize` | `-t` | `2` | Number of characters to use as tab size | | `--usetabs` | | | Use tabs instead of spaces for indentation | -| `--wraplen` | `-l` | `80` | Line length for wrapping | +| `--stdin` | `-s` | | Process stdin as a single file, output to stdout | | `--config` | | | Path to config file | -| `--help` | `-h` | | Print help | -| `--version` | `-V` | | Print version | +| `--noconfig` | | | Do not read any config file | +| `--verbose` | `-v` | | Show info messages | +| `--quiet` | `-q` | | Hide warning messages | +| `--trace` | | | Show trace messages | | `--completion` | | | Generate a shell completion script | | `--man` | | | Generate a man page | | `--args` | | | View arguments passed to tex-fmt | -| `--noconfig` | | | Do not read any config file | +| `--help` | `-h` | | Print help | +| `--version` | `-V` | | Print version | diff --git a/completion/_tex-fmt b/completion/_tex-fmt index 22cc3fc..91f28ce 100644 --- a/completion/_tex-fmt +++ b/completion/_tex-fmt @@ -15,10 +15,10 @@ _tex-fmt() { local context curcontext="$curcontext" state line _arguments "${_arguments_options[@]}" : \ -'-t+[Number of characters to use as tab size \[default\: 2\]]: :_default' \ -'--tabsize=[Number of characters to use as tab size \[default\: 2\]]: :_default' \ -'-l+[Line length for wrapping \[default\: 80\]]: :_default' \ -'--wraplen=[Line length for wrapping \[default\: 80\]]: :_default' \ +'-l+[Line length for wrapping]: :_default' \ +'--wraplen=[Line length for wrapping]: :_default' \ +'-t+[Number of characters to use as tab size]: :_default' \ +'--tabsize=[Number of characters to use as tab size]: :_default' \ '--config=[Path to configuration file]: :_files' \ '--completion=[Generate shell completion script]:shell:(bash elvish fish powershell zsh)' \ '-c[Check formatting, do not modify files]' \ @@ -27,19 +27,21 @@ _tex-fmt() { '--print[Print to stdout, do not modify files]' \ '-n[Do not wrap long lines]' \ '--nowrap[Do not wrap long lines]' \ +'--usetabs[Use tabs instead of spaces for indentation]' \ +'-s[Process stdin as a single file, output to stdout]' \ +'--stdin[Process stdin as a single file, output to stdout]' \ +'--noconfig[Do not read any config file]' \ '-v[Show info messages]' \ '--verbose[Show info messages]' \ '-q[Hide warning messages]' \ '--quiet[Hide warning messages]' \ '--trace[Show trace messages]' \ -'-s[Process stdin as a single file, output to stdout]' \ -'--stdin[Process stdin as a single file, output to stdout]' \ -'--usetabs[Use tabs instead of spaces for indentation]' \ '--man[Generate man page]' \ '--args[Print arguments passed to tex-fmt and exit]' \ -'--noconfig[Do not read any config file]' \ '-h[Print help]' \ '--help[Print help]' \ +'-V[Print version]' \ +'--version[Print version]' \ '::files -- List of files to be formatted:_default' \ && ret=0 } diff --git a/completion/_tex-fmt.ps1 b/completion/_tex-fmt.ps1 index db5fae7..ff1f7f9 100644 --- a/completion/_tex-fmt.ps1 +++ b/completion/_tex-fmt.ps1 @@ -21,10 +21,10 @@ Register-ArgumentCompleter -Native -CommandName 'tex-fmt' -ScriptBlock { $completions = @(switch ($command) { 'tex-fmt' { - [CompletionResult]::new('-t', '-t', [CompletionResultType]::ParameterName, 'Number of characters to use as tab size [default: 2]') - [CompletionResult]::new('--tabsize', '--tabsize', [CompletionResultType]::ParameterName, 'Number of characters to use as tab size [default: 2]') - [CompletionResult]::new('-l', '-l', [CompletionResultType]::ParameterName, 'Line length for wrapping [default: 80]') - [CompletionResult]::new('--wraplen', '--wraplen', [CompletionResultType]::ParameterName, 'Line length for wrapping [default: 80]') + [CompletionResult]::new('-l', '-l', [CompletionResultType]::ParameterName, 'Line length for wrapping') + [CompletionResult]::new('--wraplen', '--wraplen', [CompletionResultType]::ParameterName, 'Line length for wrapping') + [CompletionResult]::new('-t', '-t', [CompletionResultType]::ParameterName, 'Number of characters to use as tab size') + [CompletionResult]::new('--tabsize', '--tabsize', [CompletionResultType]::ParameterName, 'Number of characters to use as tab size') [CompletionResult]::new('--config', '--config', [CompletionResultType]::ParameterName, 'Path to configuration file') [CompletionResult]::new('--completion', '--completion', [CompletionResultType]::ParameterName, 'Generate shell completion script') [CompletionResult]::new('-c', '-c', [CompletionResultType]::ParameterName, 'Check formatting, do not modify files') @@ -33,19 +33,21 @@ Register-ArgumentCompleter -Native -CommandName 'tex-fmt' -ScriptBlock { [CompletionResult]::new('--print', '--print', [CompletionResultType]::ParameterName, 'Print to stdout, do not modify files') [CompletionResult]::new('-n', '-n', [CompletionResultType]::ParameterName, 'Do not wrap long lines') [CompletionResult]::new('--nowrap', '--nowrap', [CompletionResultType]::ParameterName, 'Do not wrap long lines') + [CompletionResult]::new('--usetabs', '--usetabs', [CompletionResultType]::ParameterName, 'Use tabs instead of spaces for indentation') + [CompletionResult]::new('-s', '-s', [CompletionResultType]::ParameterName, 'Process stdin as a single file, output to stdout') + [CompletionResult]::new('--stdin', '--stdin', [CompletionResultType]::ParameterName, 'Process stdin as a single file, output to stdout') + [CompletionResult]::new('--noconfig', '--noconfig', [CompletionResultType]::ParameterName, 'Do not read any config file') [CompletionResult]::new('-v', '-v', [CompletionResultType]::ParameterName, 'Show info messages') [CompletionResult]::new('--verbose', '--verbose', [CompletionResultType]::ParameterName, 'Show info messages') [CompletionResult]::new('-q', '-q', [CompletionResultType]::ParameterName, 'Hide warning messages') [CompletionResult]::new('--quiet', '--quiet', [CompletionResultType]::ParameterName, 'Hide warning messages') [CompletionResult]::new('--trace', '--trace', [CompletionResultType]::ParameterName, 'Show trace messages') - [CompletionResult]::new('-s', '-s', [CompletionResultType]::ParameterName, 'Process stdin as a single file, output to stdout') - [CompletionResult]::new('--stdin', '--stdin', [CompletionResultType]::ParameterName, 'Process stdin as a single file, output to stdout') - [CompletionResult]::new('--usetabs', '--usetabs', [CompletionResultType]::ParameterName, 'Use tabs instead of spaces for indentation') [CompletionResult]::new('--man', '--man', [CompletionResultType]::ParameterName, 'Generate man page') [CompletionResult]::new('--args', '--args', [CompletionResultType]::ParameterName, 'Print arguments passed to tex-fmt and exit') - [CompletionResult]::new('--noconfig', '--noconfig', [CompletionResultType]::ParameterName, 'Do not read any config file') [CompletionResult]::new('-h', '-h', [CompletionResultType]::ParameterName, 'Print help') [CompletionResult]::new('--help', '--help', [CompletionResultType]::ParameterName, 'Print help') + [CompletionResult]::new('-V', '-V ', [CompletionResultType]::ParameterName, 'Print version') + [CompletionResult]::new('--version', '--version', [CompletionResultType]::ParameterName, 'Print version') break } }) diff --git a/completion/tex-fmt.bash b/completion/tex-fmt.bash index 5e6c712..da57618 100644 --- a/completion/tex-fmt.bash +++ b/completion/tex-fmt.bash @@ -19,25 +19,25 @@ _tex-fmt() { case "${cmd}" in tex__fmt) - opts="-c -p -n -v -q -s -t -l -h --check --print --nowrap --verbose --quiet --trace --stdin --tabsize --usetabs --wraplen --config --completion --man --args --noconfig --help [files]..." + opts="-c -p -n -l -t -s -v -q -h -V --check --print --nowrap --wraplen --tabsize --usetabs --stdin --config --noconfig --verbose --quiet --trace --completion --man --args --help --version [files]..." if [[ ${cur} == -* || ${COMP_CWORD} -eq 1 ]] ; then COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 fi case "${prev}" in - --tabsize) + --wraplen) COMPREPLY=($(compgen -f "${cur}")) return 0 ;; - -t) + -l) COMPREPLY=($(compgen -f "${cur}")) return 0 ;; - --wraplen) + --tabsize) COMPREPLY=($(compgen -f "${cur}")) return 0 ;; - -l) + -t) COMPREPLY=($(compgen -f "${cur}")) return 0 ;; diff --git a/completion/tex-fmt.elv b/completion/tex-fmt.elv index df4f80d..bd1eee4 100644 --- a/completion/tex-fmt.elv +++ b/completion/tex-fmt.elv @@ -18,10 +18,10 @@ set edit:completion:arg-completer[tex-fmt] = {|@words| } var completions = [ &'tex-fmt'= { - cand -t 'Number of characters to use as tab size [default: 2]' - cand --tabsize 'Number of characters to use as tab size [default: 2]' - cand -l 'Line length for wrapping [default: 80]' - cand --wraplen 'Line length for wrapping [default: 80]' + cand -l 'Line length for wrapping' + cand --wraplen 'Line length for wrapping' + cand -t 'Number of characters to use as tab size' + cand --tabsize 'Number of characters to use as tab size' cand --config 'Path to configuration file' cand --completion 'Generate shell completion script' cand -c 'Check formatting, do not modify files' @@ -30,19 +30,21 @@ set edit:completion:arg-completer[tex-fmt] = {|@words| cand --print 'Print to stdout, do not modify files' cand -n 'Do not wrap long lines' cand --nowrap 'Do not wrap long lines' + cand --usetabs 'Use tabs instead of spaces for indentation' + cand -s 'Process stdin as a single file, output to stdout' + cand --stdin 'Process stdin as a single file, output to stdout' + cand --noconfig 'Do not read any config file' cand -v 'Show info messages' cand --verbose 'Show info messages' cand -q 'Hide warning messages' cand --quiet 'Hide warning messages' cand --trace 'Show trace messages' - cand -s 'Process stdin as a single file, output to stdout' - cand --stdin 'Process stdin as a single file, output to stdout' - cand --usetabs 'Use tabs instead of spaces for indentation' cand --man 'Generate man page' cand --args 'Print arguments passed to tex-fmt and exit' - cand --noconfig 'Do not read any config file' cand -h 'Print help' cand --help 'Print help' + cand -V 'Print version' + cand --version 'Print version' } ] $completions[$command] diff --git a/completion/tex-fmt.fish b/completion/tex-fmt.fish index 5e5a7ed..7f35c8c 100644 --- a/completion/tex-fmt.fish +++ b/completion/tex-fmt.fish @@ -1,16 +1,17 @@ -complete -c tex-fmt -s t -l tabsize -d 'Number of characters to use as tab size [default: 2]' -r -complete -c tex-fmt -s l -l wraplen -d 'Line length for wrapping [default: 80]' -r +complete -c tex-fmt -s l -l wraplen -d 'Line length for wrapping' -r +complete -c tex-fmt -s t -l tabsize -d 'Number of characters to use as tab size' -r complete -c tex-fmt -l config -d 'Path to configuration file' -r -F complete -c tex-fmt -l completion -d 'Generate shell completion script' -r -f -a "{bash\t'',elvish\t'',fish\t'',powershell\t'',zsh\t''}" complete -c tex-fmt -s c -l check -d 'Check formatting, do not modify files' complete -c tex-fmt -s p -l print -d 'Print to stdout, do not modify files' complete -c tex-fmt -s n -l nowrap -d 'Do not wrap long lines' +complete -c tex-fmt -l usetabs -d 'Use tabs instead of spaces for indentation' +complete -c tex-fmt -s s -l stdin -d 'Process stdin as a single file, output to stdout' +complete -c tex-fmt -l noconfig -d 'Do not read any config file' complete -c tex-fmt -s v -l verbose -d 'Show info messages' complete -c tex-fmt -s q -l quiet -d 'Hide warning messages' complete -c tex-fmt -l trace -d 'Show trace messages' -complete -c tex-fmt -s s -l stdin -d 'Process stdin as a single file, output to stdout' -complete -c tex-fmt -l usetabs -d 'Use tabs instead of spaces for indentation' complete -c tex-fmt -l man -d 'Generate man page' complete -c tex-fmt -l args -d 'Print arguments passed to tex-fmt and exit' -complete -c tex-fmt -l noconfig -d 'Do not read any config file' complete -c tex-fmt -s h -l help -d 'Print help' +complete -c tex-fmt -s V -l version -d 'Print version' diff --git a/man/tex-fmt.1 b/man/tex-fmt.1 index e5d4d6a..e872cbe 100644 --- a/man/tex-fmt.1 +++ b/man/tex-fmt.1 @@ -1,12 +1,12 @@ .ie \n(.g .ds Aq \(aq .el .ds Aq ' -.TH tex-fmt 1 "tex-fmt " +.TH tex-fmt 1 "tex-fmt 0.4.7" .SH NAME -tex\-fmt \- An extremely fast LaTeX formatter written in Rust +tex\-fmt \- LaTeX formatter written in Rust .SH SYNOPSIS -\fBtex\-fmt\fR [\fB\-c\fR|\fB\-\-check\fR] [\fB\-p\fR|\fB\-\-print\fR] [\fB\-n\fR|\fB\-\-nowrap\fR] [\fB\-v\fR|\fB\-\-verbose\fR] [\fB\-q\fR|\fB\-\-quiet\fR] [\fB\-\-trace\fR] [\fB\-s\fR|\fB\-\-stdin\fR] [\fB\-t\fR|\fB\-\-tabsize\fR] [\fB\-\-usetabs\fR] [\fB\-l\fR|\fB\-\-wraplen\fR] [\fB\-\-config\fR] [\fB\-\-completion\fR] [\fB\-\-man\fR] [\fB\-\-args\fR] [\fB\-\-noconfig\fR] [\fB\-h\fR|\fB\-\-help\fR] [\fIfiles\fR] +\fBtex\-fmt\fR [\fB\-c\fR|\fB\-\-check\fR] [\fB\-p\fR|\fB\-\-print\fR] [\fB\-n\fR|\fB\-\-nowrap\fR] [\fB\-l\fR|\fB\-\-wraplen\fR] [\fB\-t\fR|\fB\-\-tabsize\fR] [\fB\-\-usetabs\fR] [\fB\-s\fR|\fB\-\-stdin\fR] [\fB\-\-config\fR] [\fB\-\-noconfig\fR] [\fB\-v\fR|\fB\-\-verbose\fR] [\fB\-q\fR|\fB\-\-quiet\fR] [\fB\-\-trace\fR] [\fB\-\-completion\fR] [\fB\-\-man\fR] [\fB\-\-args\fR] [\fB\-h\fR|\fB\-\-help\fR] [\fB\-V\fR|\fB\-\-version\fR] [\fIfiles\fR] .SH DESCRIPTION -An extremely fast LaTeX formatter written in Rust +LaTeX formatter written in Rust .SH OPTIONS .TP \fB\-c\fR, \fB\-\-check\fR @@ -18,29 +18,32 @@ Print to stdout, do not modify files \fB\-n\fR, \fB\-\-nowrap\fR Do not wrap long lines .TP -\fB\-v\fR, \fB\-\-verbose\fR -Show info messages +\fB\-l\fR, \fB\-\-wraplen\fR [default: 80] +Line length for wrapping .TP -\fB\-q\fR, \fB\-\-quiet\fR -Hide warning messages +\fB\-t\fR, \fB\-\-tabsize\fR [default: 2] +Number of characters to use as tab size .TP -\fB\-\-trace\fR -Show trace messages +\fB\-\-usetabs\fR +Use tabs instead of spaces for indentation .TP \fB\-s\fR, \fB\-\-stdin\fR Process stdin as a single file, output to stdout .TP -\fB\-t\fR, \fB\-\-tabsize\fR -Number of characters to use as tab size [default: 2] +\fB\-\-config\fR +Path to configuration file .TP -\fB\-\-usetabs\fR -Use tabs instead of spaces for indentation +\fB\-\-noconfig\fR +Do not read any config file .TP -\fB\-l\fR, \fB\-\-wraplen\fR -Line length for wrapping [default: 80] +\fB\-v\fR, \fB\-\-verbose\fR +Show info messages .TP -\fB\-\-config\fR -Path to configuration file +\fB\-q\fR, \fB\-\-quiet\fR +Hide warning messages +.TP +\fB\-\-trace\fR +Show trace messages .TP \fB\-\-completion\fR=\fIshell\fR Generate shell completion script @@ -55,13 +58,15 @@ Generate man page \fB\-\-args\fR Print arguments passed to tex\-fmt and exit .TP -\fB\-\-noconfig\fR -Do not read any config file -.TP \fB\-h\fR, \fB\-\-help\fR Print help .TP +\fB\-V\fR, \fB\-\-version\fR +Print version +.TP [\fIfiles\fR] List of files to be formatted +.SH VERSION +v0.4.7 .SH AUTHORS William George Underwood, wg.underwood13@gmail.com diff --git a/notes.org b/notes.org index 0104de0..cc45fc1 100644 --- a/notes.org +++ b/notes.org @@ -5,10 +5,10 @@ * Options and documentation ** Args struct ** OptionArgs struct +** Implement Display for Args ** CLI command ** CLI args parser function ** Config args parser function -** Implement Display for Args ** Args resolver ** GitHub README * Release process diff --git a/src/args.rs b/src/args.rs index b22f68d..1ec8869 100644 --- a/src/args.rs +++ b/src/args.rs @@ -20,26 +20,26 @@ pub struct Args { pub print: bool, /// Wrap long lines pub wrap: bool, - /// Verbosity level for log messages - pub verbosity: LevelFilter, - /// List of files to be formatted - pub files: Vec, - /// Read from stdin and output to stdout - pub stdin: bool, - /// Number of characters to use as tab size - pub tabsize: u8, - /// Characters to use for indentation - pub tabchar: TabChar, /// Maximum allowed line length pub wraplen: u8, /// Wrap lines longer than this pub wrapmin: u8, + /// Number of characters to use as tab size + pub tabsize: u8, + /// Characters to use for indentation + pub tabchar: TabChar, + /// Read from stdin and output to stdout + pub stdin: bool, /// Path to config file pub config: Option, - /// Print arguments and exit - pub arguments: bool, /// Do not read any config file pub noconfig: bool, + /// Verbosity level for log messages + pub verbosity: LevelFilter, + /// Print arguments and exit + pub arguments: bool, + /// List of files to be formatted + pub files: Vec, } /// Arguments using Options to track CLI/config file/default values @@ -49,17 +49,17 @@ pub struct OptionArgs { pub check: Option, pub print: Option, pub wrap: Option, - pub verbosity: Option, - #[merge(strategy = merge::vec::append)] - pub files: Vec, - pub stdin: Option, - pub tabsize: Option, - pub tabchar: Option, pub wraplen: Option, pub wrapmin: Option, + pub tabsize: Option, + pub tabchar: Option, + pub stdin: Option, pub config: Option, - pub arguments: Option, pub noconfig: Option, + pub verbosity: Option, + pub arguments: Option, + #[merge(strategy = merge::vec::append)] + pub files: Vec, } /// Character to use for indentation @@ -85,16 +85,16 @@ impl Default for OptionArgs { check: Some(false), print: Some(false), wrap: Some(true), - verbosity: Some(LevelFilter::Warn), - files: vec![], - stdin: Some(false), - tabsize: Some(2), - tabchar: Some(TabChar::Space), wraplen: Some(80), wrapmin: Some(70), + tabsize: Some(2), + tabchar: Some(TabChar::Space), + stdin: Some(false), config: None, - arguments: Some(false), noconfig: Some(false), + verbosity: Some(LevelFilter::Warn), + arguments: Some(false), + files: vec![], } } } @@ -117,16 +117,16 @@ impl Args { check: args.check.unwrap(), print: args.print.unwrap(), wrap: args.wrap.unwrap(), - verbosity: args.verbosity.unwrap(), - files: args.files, - stdin: args.stdin.unwrap(), - tabsize: args.tabsize.unwrap(), - tabchar: args.tabchar.unwrap(), wraplen: args.wraplen.unwrap(), wrapmin: args.wrapmin.unwrap(), + tabsize: args.tabsize.unwrap(), + tabchar: args.tabchar.unwrap(), + stdin: args.stdin.unwrap(), config: args.config, - arguments: args.arguments.unwrap(), noconfig: args.noconfig.unwrap(), + verbosity: args.verbosity.unwrap(), + arguments: args.arguments.unwrap(), + files: args.files, } } @@ -202,6 +202,15 @@ impl fmt::Display for Args { display_arg_line(f, "check", &self.check.to_string())?; display_arg_line(f, "print", &self.print.to_string())?; display_arg_line(f, "wrap", &self.wrap.to_string())?; + display_arg_line(f, "wraplen", &self.wraplen.to_string())?; + display_arg_line(f, "wrapmin", &self.wrapmin.to_string())?; + display_arg_line(f, "tabsize", &self.tabsize.to_string())?; + display_arg_line(f, "tabchar", &self.tabchar.to_string())?; + display_arg_line(f, "stdin", &self.stdin.to_string())?; + match &self.config { + None => display_arg_line(f, "config", "None")?, + Some(c) => display_arg_line(f, "config", &c.display().to_string())?, + } display_arg_line( f, "verbosity", @@ -221,15 +230,6 @@ impl fmt::Display for Args { } } - display_arg_line(f, "stdin", &self.stdin.to_string())?; - display_arg_line(f, "tabsize", &self.tabsize.to_string())?; - display_arg_line(f, "tabchar", &self.tabchar.to_string())?; - display_arg_line(f, "wraplen", &self.wraplen.to_string())?; - display_arg_line(f, "wrapmin", &self.wrapmin.to_string())?; - match &self.config { - None => display_arg_line(f, "config", "None")?, - Some(c) => display_arg_line(f, "config", &c.display().to_string())?, - } // Do not print `arguments` or `noconfig` fields Ok(()) } diff --git a/src/cli.rs b/src/cli.rs index 8676cfe..407a66a 100644 --- a/src/cli.rs +++ b/src/cli.rs @@ -1,6 +1,7 @@ //! Functionality to parse CLI arguments use crate::args::*; +use clap::ArgMatches; use clap_complete::{generate, Shell}; use clap_mangen::Man; use log::LevelFilter; @@ -9,6 +10,15 @@ use std::io; // Get the clap CLI command from a separate file include!("command.rs"); +/// Read `ArgMatches` flag into `Option` +fn get_flag(arg_matches: &ArgMatches, flag: &str) -> Option { + if arg_matches.get_flag(flag) { + Some(true) + } else { + None + } +} + /// Parse CLI arguments into `OptionArgs` struct pub fn get_cli_args() -> OptionArgs { let mut command = get_cli_command(); @@ -32,6 +42,11 @@ pub fn get_cli_args() -> OptionArgs { } else { None }; + let tabchar = if arg_matches.get_flag("usetabs") { + Some(TabChar::Tab) + } else { + None + }; let verbosity = if arg_matches.get_flag("trace") { Some(LevelFilter::Trace) } else if arg_matches.get_flag("verbose") { @@ -41,49 +56,24 @@ pub fn get_cli_args() -> OptionArgs { } else { None }; - let tabchar = if arg_matches.get_flag("usetabs") { - Some(TabChar::Tab) - } else { - None - }; let args = OptionArgs { - check: if arg_matches.get_flag("check") { - Some(true) - } else { - None - }, - print: if arg_matches.get_flag("print") { - Some(true) - } else { - None - }, + check: get_flag(&arg_matches, "check"), + print: get_flag(&arg_matches, "print"), wrap, + wraplen: arg_matches.get_one::("wraplen").copied(), + wrapmin: None, + tabsize: arg_matches.get_one::("tabsize").copied(), + tabchar, + stdin: get_flag(&arg_matches, "stdin"), + config: arg_matches.get_one::("config").cloned(), + noconfig: get_flag(&arg_matches, "noconfig"), verbosity, + arguments: get_flag(&arg_matches, "args"), files: arg_matches .get_many::("files") .unwrap_or_default() .map(ToOwned::to_owned) .collect::>(), - stdin: if arg_matches.get_flag("stdin") { - Some(true) - } else { - None - }, - tabsize: arg_matches.get_one::("tabsize").copied(), - tabchar, - wraplen: arg_matches.get_one::("wraplen").copied(), - wrapmin: None, - config: arg_matches.get_one::("config").cloned(), - arguments: if arg_matches.get_flag("args") { - Some(true) - } else { - None - }, - noconfig: if arg_matches.get_flag("noconfig") { - Some(true) - } else { - None - }, }; args } diff --git a/src/command.rs b/src/command.rs index 7e6692c..b1f3924 100644 --- a/src/command.rs +++ b/src/command.rs @@ -7,7 +7,8 @@ use std::path::PathBuf; fn get_cli_command() -> Command { Command::new("tex-fmt") .author("William George Underwood, wg.underwood13@gmail.com") - .about("An extremely fast LaTeX formatter written in Rust") + .about(clap::crate_description!()) + .version(clap::crate_version!()) .arg( Arg::new("check") .short('c') @@ -30,29 +31,26 @@ fn get_cli_command() -> Command { .help("Do not wrap long lines"), ) .arg( - Arg::new("verbose") - .short('v') - .long("verbose") - .action(SetTrue) - .help("Show info messages"), + Arg::new("wraplen") + .short('l') + .long("wraplen") + .value_parser(value_parser!(u8)) + .default_value("80") + .help("Line length for wrapping"), ) .arg( - Arg::new("quiet") - .short('q') - .long("quiet") - .action(SetTrue) - .help("Hide warning messages"), + Arg::new("tabsize") + .short('t') + .long("tabsize") + .value_parser(value_parser!(u8)) + .default_value("2") + .help("Number of characters to use as tab size"), ) .arg( - Arg::new("trace") - .long("trace") + Arg::new("usetabs") + .long("usetabs") .action(SetTrue) - .help("Show trace messages"), - ) - .arg( - Arg::new("files") - .action(Append) - .help("List of files to be formatted"), + .help("Use tabs instead of spaces for indentation"), ) .arg( Arg::new("stdin") @@ -62,30 +60,36 @@ fn get_cli_command() -> Command { .help("Process stdin as a single file, output to stdout"), ) .arg( - Arg::new("tabsize") - .short('t') - .long("tabsize") - .value_parser(value_parser!(u8)) - .help("Number of characters to use as tab size [default: 2]"), + Arg::new("config") + .long("config") + .value_parser(value_parser!(PathBuf)) + .help("Path to configuration file") ) .arg( - Arg::new("usetabs") - .long("usetabs") + Arg::new("noconfig") + .long("noconfig") .action(SetTrue) - .help("Use tabs instead of spaces for indentation"), + .help("Do not read any config file"), ) .arg( - Arg::new("wraplen") - .short('l') - .long("wraplen") - .value_parser(value_parser!(u8)) - .help("Line length for wrapping [default: 80]"), + Arg::new("verbose") + .short('v') + .long("verbose") + .action(SetTrue) + .help("Show info messages"), ) .arg( - Arg::new("config") - .long("config") - .value_parser(value_parser!(PathBuf)) - .help("Path to configuration file") + Arg::new("quiet") + .short('q') + .long("quiet") + .action(SetTrue) + .help("Hide warning messages"), + ) + .arg( + Arg::new("trace") + .long("trace") + .action(SetTrue) + .help("Show trace messages"), ) .arg( Arg::new("completion") @@ -107,9 +111,8 @@ fn get_cli_command() -> Command { .help("Print arguments passed to tex-fmt and exit"), ) .arg( - Arg::new("noconfig") - .long("noconfig") - .action(SetTrue) - .help("Do not read any config file"), + Arg::new("files") + .action(Append) + .help("List of files to be formatted"), ) } diff --git a/src/config.rs b/src/config.rs index 48cff78..e55d6f9 100644 --- a/src/config.rs +++ b/src/config.rs @@ -101,24 +101,22 @@ pub fn get_config_args(args: &OptionArgs) -> Option { check: config.get("check").map(|x| x.as_bool().unwrap()), print: config.get("print").map(|x| x.as_bool().unwrap()), wrap: config.get("wrap").map(|x| x.as_bool().unwrap()), - verbosity, - files: vec![], - - stdin: config.get("stdin").map(|x| x.as_bool().unwrap()), - tabsize: config - .get("tabsize") - .map(|x| x.as_integer().unwrap().try_into().unwrap()), - - tabchar, wraplen: config .get("wraplen") .map(|x| x.as_integer().unwrap().try_into().unwrap()), wrapmin: config .get("wrapmin") .map(|x| x.as_integer().unwrap().try_into().unwrap()), + tabsize: config + .get("tabsize") + .map(|x| x.as_integer().unwrap().try_into().unwrap()), + tabchar, + stdin: config.get("stdin").map(|x| x.as_bool().unwrap()), config: config_path, - arguments: None, noconfig: None, + verbosity, + arguments: None, + files: vec![], }; Some(args) }