From 5cc6522776a97435e8e92c928826f3c985651dda Mon Sep 17 00:00:00 2001 From: mw98 <5422914+mw98@users.noreply.github.com> Date: Thu, 18 Nov 2021 22:51:39 +0800 Subject: [PATCH 1/4] Add {var:path} and change output to JSON --- script.rb | 39 +++++++++++++++++++++------------------ 1 file changed, 21 insertions(+), 18 deletions(-) diff --git a/script.rb b/script.rb index d71ce68..d6d8802 100644 --- a/script.rb +++ b/script.rb @@ -1,3 +1,4 @@ +require 'json' # Type a query to test with here. # !!!!! Comment this line out when pasting into alfred preferences. theQuery = "chr" @@ -14,9 +15,11 @@ # Grep for processes whose name contains the query. The regex isolates the name by only searching characters after the last slash in the path. # The -i flag ignores case. processes = `ps -A -o pid -o %cpu -o comm | grep -i [^/]*#{Regexp.quote(theQuery)}[^/]*$`.split("\n") -# Start the XML string that will be sent to Alfred. This just uses strings to avoid dependencies. -xmlString = "\n\n" +# Create a hash that will be serialised into a JSON string for Alfred. +result = {items: []} processes.each do | process | + # Create a hash for each matched process in the script filter output. + item = {variables:{}, icon: {}} # Extract the PID, CPU usage, and path from the line (lines are in the form of `123 12.3 /path/to/process`). processId, processCpu, processPath = process.match(/(\d+)\s+(\d+[\.|\,]\d+)\s+(.*)/).captures # If an argument filter has been specified, get the arguments and search for the filter. @@ -30,25 +33,25 @@ end # Use the same expression as before to isolate the name of the process. processName = processPath.match(/[^\/]*#{theQuery}[^\/]*$/i) + # Start assembling this process's JSON values. + item[:uid] = processName + item[:title] = "#{processName}#{matchedArgs.join(" ")}" + item[:arg] = processId + item[:subtitle] = "#{processCpu}% CPU @ #{processPath}" + # Add processPath to the workflow's environment variables when this item is actioned. This enables relaunching the process. + item[:variables][:path] = processPath # Search for an application bundle in the path to the process. - iconValue = processPath.match(/.*?\.app\//) + item[:icon][:path] = processPath.match(/.*?\.app\//) # The icon type sent to Alfred is 'fileicon' (taken from a file). This assumes that a .app was found. - iconType = "fileicon" + item[:icon][:type] = "fileicon" # If no .app was found, use OS X's generic 'executable binary' icon. # An empty icon type tells Alfred to load the icon from the file itself, rather than loading the file type's icon. - if !iconValue - iconValue = "/System/Library/CoreServices/CoreTypes.bundle/Contents/Resources/ExecutableBinaryIcon.icns" - iconType = "" + if !item[:icon][:path] + item[:icon][:path] = "/System/Library/CoreServices/CoreTypes.bundle/Contents/Resources/ExecutableBinaryIcon.icns" + item[:icon][:type] = "" end - # Assemble this item's XML string for Alfred. See http://www.alfredforum.com/topic/5-generating-feedback-in-workflows/ - thisXmlString = "\t - #{processName}#{matchedArgs.join(" ")} - #{processCpu}% CPU @ #{processPath} - #{iconValue} - \n" - # Append this process's XML string to the global XML string. - xmlString += thisXmlString + # Append this process's hash to the global hash. + result[:items].push(item) end -# Finish off and echo the XML string to Alfred. -xmlString += "" -puts xmlString \ No newline at end of file +# Serialise the global hash as a JSON string and echo it to Alfred. +puts result.to_json() From 9462646cc4805df769b020207f225374058e26dd Mon Sep 17 00:00:00 2001 From: mw98 <5422914+mw98@users.noreply.github.com> Date: Thu, 18 Nov 2021 23:04:04 +0800 Subject: [PATCH 2/4] Added run script for kill and relaunch --- Kill Process.alfredworkflow | Bin 5407 -> 5878 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/Kill Process.alfredworkflow b/Kill Process.alfredworkflow index b2a38705b9d4b26992e984c2fbbe297b5551bcd1..6a9d82107b2b6f5a98553bb84d69b1a7c85a2cdd 100644 GIT binary patch delta 3678 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 delta 3181 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 T78?R-6O+3ZH3k|K00000R1gbL From a40b7291113f3d5bce9e091b1033c7493e269bc5 Mon Sep 17 00:00:00 2001 From: mw98 <5422914+mw98@users.noreply.github.com> Date: Thu, 18 Nov 2021 23:15:10 +0800 Subject: [PATCH 3/4] Update feature list and remove Alfred 2 support --- Readme.md | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/Readme.md b/Readme.md index 4bbb65b..4adf15b 100644 --- a/Readme.md +++ b/Readme.md @@ -1,5 +1,5 @@ # Description -Kill Process is an Alfred 2 workflow that makes it easy to kill misbehaving processes. It is, in essence, a way to easily find processes by name and kill them using `kill -9`. +Kill Process is an Alfred 3 workflow that makes it easy to kill misbehaving processes. It is, in essence, a way to easily find processes by name and kill them using `kill -9`. # Features * Autocompletes process names @@ -10,6 +10,7 @@ Kill Process is an Alfred 2 workflow that makes it easy to kill misbehaving proc * Shows process paths * Ignores case * Kills all processes with matching names on cmd+return +* Kills and relaunches a process on shift+return * Supports [Alleyoop updating](http://www.alfredforum.com/topic/1582-alleyoop-update-alfred-workflows/). ![screenshot: `kill it`](screenshot1.png) @@ -19,8 +20,9 @@ Kill Process is an Alfred 2 workflow that makes it easy to kill misbehaving proc 1. Type `kill` into Alfred followed by a space. 2. Begin typing the name of the process you want to kill. 3. When you see the process you want to kill, select it from the list as usual. -4. Press return to kill the selected process. -Alternatively, press cmd+return to kill all processes with the same name as the selected one. +4. Press return to kill the selected process. Alternatively: + - Press cmd+return to kill all processes with the same name as the selected one. + - Press shift+return to relaunch the selected process after killing it. To filter by argument, add a colon and the argument you want to target (or a snippet of it) after your processes name (see the [second screenshot](screenshot2.png)). From de50070abf7378adc6b5c8237770052284a6b031 Mon Sep 17 00:00:00 2001 From: mw98 <5422914+mw98@users.noreply.github.com> Date: Fri, 19 Nov 2021 01:52:17 +0800 Subject: [PATCH 4/4] Fix issue with file paths containing spaces --- Kill Process.alfredworkflow | Bin 5878 -> 5866 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/Kill Process.alfredworkflow b/Kill Process.alfredworkflow index 6a9d82107b2b6f5a98553bb84d69b1a7c85a2cdd..9027249ca42b385952ee802e4788a45c8277061f 100644 GIT binary patch delta 3150 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 delta 3162 zcmV-g45jnxE%q(2V+RerwQ^Hs+6_sg4FCYmlW+$X1}0~gVJBykj0Yqp!;z%M;0||b z!j)utH^7}`X>F^>lB!(+KEiju-?OVX8$*H1wbPT<2QmS9vk3@L0T#hjn2q1mcDP_y zo}4l{^#lv-88?4plWz$tf5?4137k|Ssg(XVq3l_?@2HcHWBCjCU9WY}-#KXS812pN zhS6yrc8r~N118wsYPEaq{heNC@JH~wLV)=*9pPebOYV;5%klEPEvI(CzRx2jt9@6B zpY`QX2}wG!7m*~FK^@w{^XF{r1unDkOR<*CJTc-^`w|-pM>6j~fAxet@_7->bLP}C zdD}8J<(|hH;xf2!^fSVF5z7msD!ea^`(tlX2zA+Pu!2zay^ zXd$l9z7m?T!)|^_cs##dVGR1H9Z%#u;!i|4_I&<0lY1oaay+|xEQ7C;uz3~67h^v} z6`*phnF*nUTme~df6-@WM(sJegeZZ_s9y|vB@cRV*1}8SGLjzn(>MuI$AYf#*MrK0oNqo`>-%R`+DTz%Q(1RfHzTSYfANJK-)e z(cDRd3}-8o+$v1PK?s7o9>nO+y}*+ma{j~KUL1Xr1l6(oe@?8VF;0R2?B1U%28gwb zk=0z4fbWeqG5;m;V$Rlo7GbbnSz{leU1l?7OiYGMB5~@nXUb!4V#iDRVf}DM#-LNb z?**KN2{ul7z#^M+?Sz4ykZEfNeSD1b0f+<)Ipu#>2wt$E#e{O?#6<B_W{*j&wAY6PF@e8RmPri65jmP;Pm9Ex z1R>~Ujx8Xrg22~o7zq-b7ELCZTqvK}gt!8j(|=j#uhwpUByuD3mn4+DmZ`mdt5&}n zX8J!1U;t~ZuMz=VcS`gr|4|Aaaj+F5rg;Jef3JO#{q^L-`?4KtcQ7kD9f8st4@pJr zveWb1f&)|8k{g23^cnkHd9jR|;1x!vd|&TPWu{|M<}QdDQ6kOC3qnYUFKrMDBNn?i zw;RlZDtFnph5F+kzzIpPRH zOc6j{>ag>IF?dl5nO}1!ktFrP^9yVme?_UoV?Wpzr68lSgVK1;jWRz?iFPwhtqEcn zTcl9=M8wu^a*5w&9sx37<&GWHEXdHfX>PP&{Ac2hZ{*z7({;Yg)ctyD5w4=gBV87f9xm^20Df70)PSq{_7qBQ47J>qhoqwoDL_>!{HI(?iE{^v@VrMni#XHHJ+2=Bu}7G!8wpETwHq zA#_SrJ8&3sqr6Z7gX`40(S~(YLU6!9hdP^FpVw0Af60eI`7&{Y zNGUIaTulR05H6kEpgN3wIAQ;Qf+jpbLUGu7DQt|qz>eqZiUCvUIbfTN=10@UYkCFEwFqM6w2-=@%Rc#`upeMx%Uw?U5_NaDODx_+i%mo&# zcit!l=~f?ZeZu2Q4|-Bxf2a}`rq(zfpf*P^w0`6wOk&z|m~+3cm_H&iJSPyKo`O4f zrU+mq14EsXNOB%RW6JQ~)DP6^zuWZT{*FfnMIcwa5G!&=t!gb^PSp zk6+Po^A8&Vk;-UAaQ@)#4eao_ zBgv#ovot}22&gx)0k31y@?+%#`Y<*uyL)N~nR189Q&PRCiRzW@UnsH3X&fdK zjnyjwEm(g~r6uLKB-ShR<_M=XG>k;c5B3GAvXB0D0`FW~J9IsnDfdK$ql%hbC$NNc za;m~k1oMamTaHshy~m74Lz4|?aHn2;m>|x$e=bZ(O^eiIW0(z{hWTXFi=ky2n3AC} zkHBkys|^#4zKt?hfrTYOtAACkK?J@>q( z`f2f9s{GBYrCNMN^Pxv$e1rrPt5>xacanz-xcCJ5I~l3UD^Rbb74M)~zw!=mM*E(n zUK@T>`7g6H6$=3ky|r>vW!eo%qYVH6&67+PBmyR9lX4b20YH