function todo()
{
# recursively search for TODO followed by colon, or [ ] with an underscore in between.
findtext ("TODO" + ":|\[_\]")
}
...which relies on my ever-evolving sense of 'findtext'
Currently something like.... (this is dynamically loaded from util)
[string[]] $fileTypes = "*.md", "*.fmw", "*.txt", "*.cs", "*.cshtml", "*.css", "*.ps1", "*.js", "*.bat", "*.vbs", "*.vb", "*.xml", "*.config", "*.htm", "*.html", "*.pre", "*.ini", "*.sql", "*.linq", "*.json", "*.spark", "*.ts", "*.psm1", "*.psd1", "*.aspx", "*.ascx", "*.asp", "*.asmx", "*.pubxml", "*.dgml", "*.sln", "*.*proj", "*.spark", "*.rdl", "*.py", "*.log", "*.las", "*.ascx", "*.inc", "*.xaml", "*.sh", "*.csv", "*.tsv", "*.php", "*.ok", "*.tsx", "*.targets", "*.yml", "*.yaml", "*.rdp", "*.less", "*.scss", "*.razor", "*.dbml", "*.layout", "*.gradle", "*.properties", "*.bas", "*.java", "*.m", "*.h", "*.iml", "*.swift", "*.xib", "*.strings", "*.storyboard", "*.kt", "*.xcconfig", "*.plist", "*.toml", "*.webmanifest", "*.prettierrc", "*.code-workspace", "*.gitignore", "*.hgignore", "*.dockerignore", "*.tt", "*.hta", "*.lock";
## Commands:
## findtext $pattern <-- search all text type files for a particular regex
### if the pattern is not valid as a regex we'll treat it as a literal string.
### The complete list of filetypes is in this variable: $fileTypes
## findtext_raw $pattern <-- search all text type files for a literal string.
## findtext_type $types $pattern $recurse <-- e.g. findtext_type "*.tsx" "import"
## findtext_raw_type $pattern <-- search all text type files for a literal string.
## findtext_raw_casesensitive $pattern <-- enforce case sensitivity!
## findtext_norecurse <-- findtext but avoid recursing into child folders
### same as: `format-findtext $pattern $false`
## findtext_help <-- help on findtext and related commands
## findtext_help_detailed <-- verbose help on findtext, with details.
### find-text ($pattern, $recursive, $basePath, $Raw, $CaseSensitive)
### format-findtext ($pattern, $recursive, $raw, $CaseSensitive)
### <-- (aliased as findtext) sends find-text to format-foundtext
### format-foundtext ($result, $raw, $caseSensitive)
function find-text {
<#
.SYNOPSIS
Looks for regex or (if $raw -eq $true) literal text patterns in all text files (but ignores `node_modules` folders, yay)
.DESCRIPTION
Ever need to find some text, or perhaps a regex, in every text file under the current location, and want to skip any node_modules folders (and any .git folders) -- looking *only* in "text" files, such as all code and config files? Find-Text is your friend.
.NOTES
Author: Leon Bambrick
#>
Param (
# A regular expression or a literal string you wish to find in any text file
[ValidateNotNullOrEmpty()]
[String]
$Pattern,
[Bool]
# search all subfolders as well (defaults to $true)
$Recursive = $true,
[String]
# the folder from which the command is executed (used for displaying shorter paths)
$BasePath = (Get-Location | ForEach-Object { $_.ProviderPath }),
[Bool]
# $true to search for literal pattern, $false (the default) to search for regular expressions
$Raw = $false,
[Bool]
$CaseSensitive = $false,
[String[]]
$overRideWithFileTypes = $null
)
if ($overRideWithFileTypes -eq $null) {
$overRideWithFileTypes = $fileTypes;
}
Get-ChildItem -Path * -Include $overRideWithFileTypes -Exclude .git, .hg, *jquery*, modernizr* -Recurse:$Recursive |
Where-Object { $_.FullName -inotmatch 'node_modules' } |
Select-String -Pattern $pattern -SimpleMatch:$Raw -CaseSensitive:$CaseSensitive |
ForEach-Object {
Add-Member -InputObject $_ -MemberType NoteProperty -Name "RelativeName" -Value ($_.Path.SubString($basePath.Length + 1));
$_;
}
}
#
# NOTE: the alias FINDTEXT points here!
#
function format-findtext($pattern, $recursive, $raw, $CaseSensitive) {
if ($null -eq $pattern) {
Write-Host "Please provide a Pattern you wish to find (all text files will be searched)" -ForegroundColor "red"
return
}
if ($null -eq $recursive) {
#"SETTING RECURSIVE"
$recursive = $true
}
else {
#"recursive was not null it was $recursive"
}
if ($null -eq $raw) {
# RAW (meaning, simple match, not regex match) defaults to FALSE
$raw = $false;
}
if ($null -eq $CaseSensitive) {
# 'CaseSensitive' defaults to FALSE
$CaseSensitive = $false;
}
$basePath = (Get-Location | ForEach-Object { $_.ProviderPath })
# write-host $pattern -f magenta
# write-host $recursive -f magenta
# write-host $raw -f magenta
# write-host $CaseSensitive -f magenta
try {
return (find-text $pattern $recursive $basePath $raw $caseSensitive |
ForEach-Object {
format-foundtext $_ $raw $caseSensitive;
} );
}
catch {
Write-Host $_ -f darkred;
if ($_.FullyQualifiedErrorId -eq "InvalidRegex,Microsoft.PowerShell.Commands.SelectStringCommand") {
Write-Host "Falling back to a simple match..." -ForegroundColor "green";
format-findtext -pattern:$pattern -recursive:$recursive -raw:$true -casesensitive:$CaseSensitive
}
}
}
function format-foundtextdimmed ($result, $len1, $raw, $caseSensitive) {
Write-Host $result.RelativeName.SubString(0, $len1) -f darkblue -n;
Write-Host "$($result.RelativeName.SubString($len1)) " -f cyan -n;
Write-Host "$($result.LineNumber) " -f yellow -n;
Write-MarkedPatternInline ($result.Pattern) ($result.Line.Trim()) $raw $caseSensitive;
Write-Host "";
}
$script:previous = $null;
function format-foundtext ($result, $raw, $caseSensitive) {
$dimLength = FindLongestCommonStartingSubString ($result.RelativeName) ($script:previous.RelativeName);
# specify what to break on... it returns how many parts in common.... or num chars.
#format-foundtext-old $result $dimLength $raw $caseSensitive
format-foundtextdimmed $result $dimLength $raw $caseSensitive
$script:previous = $result;
$script:previousDimLength = $dimLength;
}
function format-foundtext-old ($result) {
Write-Host "$($result.RelativeName) " -f white -n;
Write-Host "$($result.LineNumber) " -f yellow -n;
Write-MarkedPatternInline ($result.Pattern) ($result.Line);
Write-Host "";
}
# same as findtext but does not use recursive
function findtext_norecurse($pattern) {
format-findtext $pattern $false
}
# Pattern is not treated as regular expression -- it's a "simplematch" instead
function findtext_raw($pattern, $recursive) {
return format-findtext $pattern $recursive $true;
}
function findtext_raw_casesensitive($pattern, $recursive, $raw) {
return format-findtext $pattern $recursive $raw $true;
}
function findtext_raw_type($types, $pattern, $recursive) {
$originalTypes = $fileTypes;
$fileTypes = $types;
findtext_raw $pattern $recursive;
$fileTypes = $originalTypes;
}
function findtext_type($types, $pattern, $recursive, $CaseSensitive) {
$originalTypes = $fileTypes;
$fileTypes = $types;
format-findtext $pattern $recursive -caseSensitive $caseSensitive;
$fileTypes = $originalTypes;
}
function findtext_help () {
$x = (& { $myInvocation.ScriptName })
Get-Content $x | Where-Object { $_ -like "## *" } | ForEach-Object { $_.TrimStart("#") }
}
function findtext_help_detailed() {
$x = (& { $myInvocation.ScriptName })
Get-Content $x | Where-Object { ($_ -like "## *") -or ($_ -like "### *") } | ForEach-Object {
Write-MarkedPatternInline "format|_|find|text|<--" ($_.TrimStart("#")) $false $false;
Write-Host "";
}
}
function FindLongestCommonStartingSubString($string1, $string2) {
$i = 0;
$max = 0;
do {
$string1.ToCharArray() | ForEach-Object {
if ($null -ne $string2 -and $i -le $string2.length -and $_ -eq $string2[$i]) {
$max = ($i + 1);
}
else { break; };
$i++;
}
} while ($false);
return $max;
}
function list-functions () {
#find-text "^\s*function( )" | % { New-Object psobject -property @{
find-text "^\s*function(.*)" $true ".\" $false $false | % { New-Object psobject -Property @{
FileName = $_.FileName;
FunctionName = ($_.Line -split '[ (]')[1]
} } | ? { $_.FunctionName -ne '' }
}
## LITTLE ALIASES
## (there could be an exit here if you have set the "do not set aliases" flag; And/or a way to delete aliases that were put here incorrectly.)
Set-Alias findtext format-findtext
Set-Alias fi format-findtext # can't use "ft", it's "format-table" already
Set-Alias f format-findtext
Set-Alias f.raw findtext_raw
Set-Alias f.type findtext_type
Set-Alias f.type-raw findtext_raw_type
Set-Alias f.raw-type findtext_raw_type
Set-Alias findtext_type_raw findtext_raw_type
Set-Alias f.raw-ci findtext_raw_casesensitive
Set-Alias f.no-rec findtext_norecurse
Set-Alias ftx findtext_norecurse
<#
find-text "Select" | % { [System.IO.DirectoryInfo]$_.Path } | % Extension | group
find-text "Select" | % { $last = ($_.Path -split "\." | select -last 1); $last; } | group;
#>