Skip to content

Commit

Permalink
Add Sort
Browse files Browse the repository at this point in the history
  • Loading branch information
phil294 committed Jul 20, 2023
1 parent c18e645 commit ad8bd21
Show file tree
Hide file tree
Showing 3 changed files with 76 additions and 11 deletions.
8 changes: 4 additions & 4 deletions README.md
Expand Up @@ -55,7 +55,7 @@ AHK_X11 can be used completely without a terminal. You can however if you want u
<details><summary><strong>CLICK TO SEE WHICH COMMANDS ARE IMPLEMENTED AND WHICH ARE MISSING</strong>. Note however that this is not very representative. For example, no `Gui` sub command is included in the listing. For a better overview on what is already done, skim through the <a href="https://phil294.github.io/AHK_X11"><b>FULL DOCUMENTATION HERE</b></a>.</summary>

```diff
DONE ?% (107/220):
DONE ?% (108/220):
+ Else, { ... }, Break, Continue, Return, Exit, GoSub, GoTo, IfEqual, Loop, SetEnv, Sleep, FileCopy,
+ SetTimer, WinActivate, MsgBox, Gui, SendRaw, #Persistent, ExitApp,
+ EnvAdd, EnvSub, EnvMult, EnvDiv, ControlSendRaw, IfWinExist/IfWinNotExist, SetWorkingDir,
Expand All @@ -70,7 +70,7 @@ DONE ?% (107/220):
+ WinGetTitle, WinGetClass, PixelGetColor, CoordMode, GuiControl, ControlGetPos, ControlGetText,
+ WinGet, Input, Loop (parse a string), ToolTip, If var [not] in/contains MatchList, ControlSetText,
+ PixelSearch, #Include, InputBox, ClipWait, EnvSet, SetKeyDelay, SetMouseDelay, MouseClickDrag,
+ #NoTrayIcon, TrayTip, Random, Shutdown, RunAs, SoundGet, SoundSet, SoundPlay
+ #NoTrayIcon, TrayTip, Random, Shutdown, RunAs, SoundGet, SoundSet, SoundPlay, Sort

NEW ?% (9/220): (not part of spec or from a more recent version)
@@ Echo, ahk_x11_print_vars, FileRead, RegExGetPos, RegExReplace, EnvGet, Click @@
Expand All @@ -85,7 +85,7 @@ REMOVED ?% (11/220):
# AutoTrim: It's always Off. It would not differentiate between %a_space% and %some_var%.
# It's possible but needs significant work.

TO DO ?% (89/220): alphabetically
TO DO ?% (88/220): alphabetically
- BlockInput, Control, ControlFocus, ControlGet, ControlGetFocus,
- ControlMove,
- DetectHiddenText, DetectHiddenWindows, Drive, DriveGet, DriveSpaceFree,
Expand All @@ -100,7 +100,7 @@ TO DO ?% (89/220): alphabetically
- Process, Progress, SetBatchLines,
- SetCapslockState, SetControlDelay, SetDefaultMouseSpeed, SetFormat,
- SetNumlockState, SetScrollLockState, SetStoreCapslockMode, SetTitleMatchMode,
- SetWinDelay, Sort, SoundGetWaveVolume,
- SetWinDelay, SoundGetWaveVolume,
- SoundSetWaveVolume, SplashImage, SplashTextOn, SplashTextOff, SplitPath, StatusBarGetText,
- StatusBarWait, StringCaseSense, StringSplit, StringTrimLeft, StringTrimRight,
- SysGet, Thread, Transform, WinActivateBottom,
Expand Down
14 changes: 7 additions & 7 deletions docs/index.html
Expand Up @@ -590,7 +590,7 @@ <h2>Table of contents </h2>
<a class="tbd" href="#SetFormat.htm">SetFormat</a>
</li>
<li>
<a class="tbd" href="#Sort.htm">Sort</a>
<a href="#Sort.htm">Sort</a>
</li>
<li>
<a class="tbd" href="#StringCaseSense.htm">StringCaseSense</a>
Expand Down Expand Up @@ -2586,7 +2586,7 @@ <h2 class="calibre9"><span class="calibre23">The "Last Found" Window </span></h2
<td height="16" class="calibre4">Waits the specified amount of time before continuing. </td>
</tr>
<tr class="calibre3">
<td height="16" class="tbd calibre4"><a href="#Sort.htm" class="pcalibre3 pcalibre1 pcalibre calibre5 pcalibre2">Sort</a></td>
<td height="16" class="calibre4"><a href="#Sort.htm" class="pcalibre3 pcalibre1 pcalibre calibre5 pcalibre2">Sort</a></td>
<td height="16" class="calibre4">Arranges a variable's contents in alphabetical or numerical order.</td>
</tr>
<tr class="calibre3">
Expand Down Expand Up @@ -11869,7 +11869,7 @@ <h2 id="Examples">Examples</h2>
MsgBox But the file is not open in either Metapad or Notepad.</pre>
</div>
</div>
<div class="calibreMain tbd">
<div class="calibreMain">
<div class="calibreEbookContent">
<a id="Sort.htm" href="#Sort.htm">#</a> <h2 class="calibre17">Sort</h2> [v1.0.13+]
<hr size="2" class="calibre24" />
Expand Down Expand Up @@ -11907,14 +11907,14 @@ <h2 id="Examples">Examples</h2>
<p class="calibre8"><strong class="calibre14">N</strong>: Numeric sort: Each item is assumed to be a number rather than a string (for example, if this option is not present, the string 233 is considered to be less than the string 40 due to alphabetical ordering). Both decimal and hexadecimal strings (e.g. 0xF1) are considered to be numeric. Strings that don't start with a number are considered to be zero for the purpose of the sort. Numbers are treated as 64-bit signed values.</p>
<p class="calibre8"><strong class="calibre14">Pn</strong>: Sorts items based on character position <strong class="calibre14">n</strong> (do not use hexadecimal for <strong class="calibre14">n</strong>). If this option is not present, <strong class="calibre14">n</strong> defaults to 1, which is the position of the first character. The sort compares each string to the others starting at its <strong class="calibre14">n</strong>th character. If <strong class="calibre14">n</strong> is greater than the length of any string, that string is considered to be blank for the purpose of the sort. When used with option <strong class="calibre14">N</strong> (numeric sort), the string's character position is used, which is not necessarily the same as the number's digit position.</p>
<p class="calibre8"><strong class="calibre14">R</strong>: Sorts in reverse order (alphabetically or numerically depending on the other options).</p>
<p class="calibre8"><strong class="calibre14">Random</strong> [v1.0.24+]: Sorts in random order. This option causes all other options except <strong class="calibre14">D</strong> and <strong class="calibre14">Z</strong> to be ignored. Examples:<br class="calibre12" /> Sort, MyVar, Random<br class="calibre12" /> Sort, MyVar, Random Z D| </p>
<p class="calibre8"><strong class="calibre14">Random</strong> Sorts in random order. This option causes all other options except <strong class="calibre14">D</strong> and <strong class="calibre14">Z</strong> to be ignored. Examples:<br class="calibre12" /> Sort, MyVar, Random<br class="calibre12" /> Sort, MyVar, Random Z D| </p>
<p class="calibre8"><strong class="calibre14">Z</strong>: To understand this option, consider a variable that contains RED`nGREEN`nBLUE`n. If the <strong class="calibre14">Z</strong> option is not present, the last linefeed (`n) is considered to be part of the last item, and thus there are only 3 items. But by specifying the Z option, the last linefeed (if present) will be considered to delimit a blank item at the end of the list, and thus there are 4 items (the last being blank).</p>
<p class="calibre8"><strong class="calibre14">\</strong> (backslash): Sorts items based on the substring that follows the last backslash in each. If an item has no backslash, the entire item is used as the substring. This option is useful for sorting bare filenames (i.e. excluding their paths). In the example below, the AAA.txt line is sorted above the BBB.txt line because their directories are ignored for the purpose of the sort:<br class="calibre12" /> C:\BBB\AAA.txt<br class="calibre12" /> C:\AAA\BBB.txt<br class="calibre12" /> Note: Options <strong class="calibre14">N</strong> and <strong class="calibre14">P</strong> are ignored when the backslash option is present. </p>
<p class="calibre8 tbd"><strong class="calibre14">\</strong> (backslash): Sorts items based on the substring that follows the last backslash in each. If an item has no backslash, the entire item is used as the substring. This option is useful for sorting bare filenames (i.e. excluding their paths). In the example below, the AAA.txt line is sorted above the BBB.txt line because their directories are ignored for the purpose of the sort:<br class="calibre12" /> C:\BBB\AAA.txt<br class="calibre12" /> C:\AAA\BBB.txt<br class="calibre12" /> Note: Options <strong class="calibre14">N</strong> and <strong class="calibre14">P</strong> are ignored when the backslash option is present. </p>
<p class="calibre8"> </p>
<p class="calibre8"><strong class="calibre14">Remarks</strong></p>
<p class="calibre8">This command is typically use to sort a variable that contains a list of lines, with each line ending in a linefeed (`n) character.</p>
<p class="calibre8">If <em class="calibre21">VarName</em> is clipboard and the clipboard contains files (such as those copied from an open Explorer window), those files will be replaced with a sorted list of their filenames. In other words, after the operation, the clipboard will no longer contain the files themselves.</p>
<p class="calibre8">If VarName is an <a href="#Variables.htm__env" class="pcalibre3 pcalibre1 pcalibre calibre5 pcalibre2">environment variable, </a>a script variable will be created to take its place. To put the sorted contents back into the environment variable and force the script to access it in the future, use this example:<br class="calibre12" /> VarSort, MyEnvVar<br class="calibre12" /> EnvSet, MyEnvVar, %MyEnvVar%<br class="calibre12" /> MyEnvVar = ; make the script's variable blank so that MyEnvVar will be retrieved from the environment in the future. </p>
<p class="calibre8 rm">If <em class="calibre21">VarName</em> is clipboard and the clipboard contains files (such as those copied from an open Explorer window), those files will be replaced with a sorted list of their filenames. In other words, after the operation, the clipboard will no longer contain the files themselves.</p>
<p class="calibre8 rm">If VarName is an <a href="#Variables.htm__env" class="pcalibre3 pcalibre1 pcalibre calibre5 pcalibre2">environment variable, </a>a script variable will be created to take its place. To put the sorted contents back into the environment variable and force the script to access it in the future, use this example:<br class="calibre12" /> VarSort, MyEnvVar<br class="calibre12" /> EnvSet, MyEnvVar, %MyEnvVar%<br class="calibre12" /> MyEnvVar = ; make the script's variable blank so that MyEnvVar will be retrieved from the environment in the future. </p>
<p class="calibre8">The maximum capacity of a variable can be increased via <a href="#h_MaxMem.htm" class="pcalibre3 pcalibre1 pcalibre calibre5 pcalibre2">#MaxMem</a>.</p>
<p class="calibre8">If a large variable was sorted and later its contents are no longer needed, you can free its memory by making it blank, e.g. MyVar = </p>
<p class="calibre8"> </p>
Expand Down
65 changes: 65 additions & 0 deletions src/cmd/string/sort.cr
@@ -0,0 +1,65 @@
# Sort, VarName [, Options]
class Cmd::String::Sort < Cmd::Base
def self.min_args; 1 end
def self.max_args; 2 end
def run(thread, args)
var = args[0]
old_value = thread.get_var(var)
opt = args[1]? || ""
delimiter = '\n'
d_index = opt.index('D')
if d_index
d_char = opt[d_index + 1]?
delimiter = d_char if d_char
end
case_sensitive = opt.includes?('C')
numeric = opt.includes?('N')
p_index = opt.index('P')
pos = 1
if p_index
p_char = opt[p_index + 1]?
pos = p_char.to_i if p_char
end
pos -= 1
reverse = opt.includes?('R')
random = opt.includes?("Random")
rand = ::Random.new
z_option = opt.includes?('Z')
split = old_value.split(delimiter)
if ! z_option
if split.last?
if split.last.empty?
split.pop
split[split.size - 1] += delimiter
end
end
end
sorted = split.sort do |a, b|
puts "sort iter"
if random
next rand.next_bool ? 1 : -1
end
if pos > 0
a = a[pos..]? || ""
b = b[pos..]? || ""
end
if numeric
a = a.to_f
b = b.to_f
ret = a <=> b
else
if ! case_sensitive
a = a.downcase
b = b.downcase
end
ret = a <=> b
end
ret
end
if reverse
sorted.reverse!
end
new_value = sorted.join(delimiter)
thread.runner.set_user_var(var, new_value)
end
end

0 comments on commit ad8bd21

Please sign in to comment.