├── screenshots ├── 1.png ├── 2.png └── 3.png ├── README.md └── cmdfetch.lua /screenshots/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hal-ullr/cmdfetch/HEAD/screenshots/1.png -------------------------------------------------------------------------------- /screenshots/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hal-ullr/cmdfetch/HEAD/screenshots/2.png -------------------------------------------------------------------------------- /screenshots/3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hal-ullr/cmdfetch/HEAD/screenshots/3.png -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ###History 2 | --- 3 | This is version 5.0.2 of CMDFetch. CMDFetch is a clone of screenfetch/screenfo for Windows written in Lua. CMDFetch was written as a batch file and distributed with proprietary binaries until version 2.0.0. Version 2.0.0 and later are written in Lua with no proprietary dependencies Version 2.1.5 was re-written from the bottom up as version 3.0.0 with several new features. Version four was a feature clone of Version three with a cleaner code base, but it never saw completion. Version five is a rewrite of Version four with a modified feature set. Versions 3.0.0 to 4.0.0 are source independent of versions predating 2.0.0 like Winfetch, but are a continuation of the project and contain fragments of code from versions after 2.0.0. Versions 5.0.0 and after are source independent of all previous versions, but functionally comparable. 4 | 5 | ###Arguments: 6 | --- 7 | ``` 8 | -0, --nocolor Force the use of zero colors 9 | -1, --18color Force the use of 18 colors 10 | -2, --256color Force the use of 256 colors 11 | -a, --align Align the information into columns 12 | -b, --block [#>0] Use a stripe step as high and as wide as the argument 13 | -c, --color color Change the color of the logo 14 | See --help color for formatting help 15 | -h, --help 16 | -l, --logo logo Change the logo 17 | windows8, windows7, linux, mac (defaults to 7 or 8) 18 | -L, --lefty Toggle the switching of logo and information 19 | -s, --stripe [dir] Stripe the colors for the logo à la screenfo 20 | vertical, horizontal, none 21 | -v, --vert alignment Align the shorter column vertically 22 | center,top,bottom (defaults to center) 23 | -m, --margin #,# Set the padding around the logo 24 | ``` 25 | 26 | ###Requires: 27 | --- 28 | + A lua interpreter: 29 | https://github.com/rjpcomputing/luaforwindows/ 30 | After installation you can use "lua cmdfetch.lua" to run cmdfetch 31 | in your favorite Unix shell or CMD. 32 | [ http://www.mediafire.com/?eku77kh2i9f14pm ] 33 | This is a packaged Lua binary, keeps the footprint small. 34 | + A method of ANSI escape codes: 35 | http://adoxa.altervista.org/ansicon/ 36 | This is an application that adds ANSI escape codes to CMD 37 | >NOTE: Any Cygwin PTY will do instead of this. 38 | >The Cygwin Terminal or "Mintty" is installed with 39 | >the Cygwin base and works fine, you can use Lua in cygwin. As of v.4.0.0, 40 | >this is the recommended course of action. 41 | >After you download it, run it and you can use it as you would CMD 42 | 43 | + Lua Socket if you want the "Now Playing" line to work. 44 | + Foobar Control Server if you want the "Now Playing" line to work with foobar. 45 | https://code.google.com/p/foo-controlserver/ 46 | 47 | ###Screenshots: 48 | --- 49 |

50 | CMDFetch 51 | CMDFetch 52 | CMDFetch 53 |

54 | ###Changelog 55 | --- 56 | 57 | ####Version 5.0.1 58 | 59 | + Fixed Visual Style 60 | + Removed bold colors from color scale 61 | + Minor fixes 62 | 63 | ####Version 5.0.2 64 | 65 | + Removed bold colors from name 66 | + Removed extraneous logos 67 | + Minor fixes 68 | -------------------------------------------------------------------------------- /cmdfetch.lua: -------------------------------------------------------------------------------- 1 | #!/bin/lua 2 | ---- CMDFetch v.5.0.0 3 | ---- See "cmdfetch --help" or "cmdfetch -h" for documentation 4 | ---- Made by Hal in Lua 5.2 for Windows 7 or 8 with or without Cygwin 5 | ---- Thanks to Zanthas and the rest of the original CMDFetch team 6 | ---- Thanks to KittyKatt and the makers of screenfo 7 | 8 | xpcall(function() require("socket") end,nil) 9 | xpcall(function() require("socket/socket") end,nil) 10 | 11 | 12 | 13 | 14 | 15 | local help = ( 16 | [[Write an OS logo to the output with relevant information. 17 | 18 | -0, --nocolor Force the use of zero colors 19 | -1, --18color Force the use of 18 colors 20 | -2, --256color Force the use of 256 colors 21 | -a, --align Align the information into columns 22 | -b, --block [#>0] Use a stripe step as high and as wide as the argument 23 | -c, --color color Change the color of the logo 24 | See --help color for formatting help 25 | -h, --help 26 | -l, --logo logo Change the logo 27 | windows8, windows7, linux, mac, none 28 | -L, --lefty Toggle the switching of logo and information 29 | -s, --stripe [dir] Stripe the colors for the logo à la screenfo 30 | vertical, horizontal, none 31 | -v, --vert alignment Align the shorter column vertically 32 | center,top,bottom (defaults to center) 33 | -m, --margin #,# Set the padding around the logo 34 | 35 | v.5.0.2 by Hal, Zanthas, tested (and approved) by KittyKatt, other people]]) 36 | 37 | local colorhelp = ( 38 | [[The following patterns are acceptable: 39 | 40 | 16-255: 41 | Ex. ←[38;5;87m87←[0m; ←[1;31m9←[0m 42 | black,red,green,yellow,blue,magenta,cyan,white: 43 | Ex. ←[0;33myel←[1;33mlow←[0m; ←[0;34mbl←[1;34mue←[0m 44 | List: 45 | Ex. ←[1;30m8←[0m,←[38;5;52m52←[0m,←[0;31mred←[0m,←[1;31mlightred←[0m 46 | none: 47 | Ex. none 48 | rainbow: 49 | Ex. ←[1;31mr←[1;33ma←[1;32mi←[1;36mn←[1;34mb←[1;35mo←[1;31mw←[0m 50 | 51 | If you are seeing arrows followed by brackets, numbers, and semicolons 52 | you have no color support in your terminal.]]) 53 | 54 | 55 | 56 | 57 | 58 | local fhost,fport = "localhost","3333" 59 | local mhost,mport = "localhost","6600" 60 | 61 | local options = { 62 | align = true, 63 | lefty = true, 64 | bars = true, 65 | bright = false, 66 | dull = false, 67 | vert = "center", 68 | logo = true, 69 | info = true, 70 | margins = {1,2}, 71 | stripe = 0, 72 | block = 1, 73 | } 74 | 75 | local order = { 76 | "Name","OS","Uptime","Kernel","Now Playing","Visual Style","Memory", 77 | "Disk Space","CPU","GPU" 78 | } 79 | 80 | 81 | 82 | 83 | local logos = { 84 | windows8 = { " ....::::", 85 | " ....::::::::::::", 86 | " ....:::: ::::::::::::::::", 87 | "....:::::::::::: ::::::::::::::::", 88 | ":::::::::::::::: ::::::::::::::::", 89 | ":::::::::::::::: ::::::::::::::::", 90 | ":::::::::::::::: ::::::::::::::::", 91 | ":::::::::::::::: ::::::::::::::::", 92 | "................ ................", 93 | ":::::::::::::::: ::::::::::::::::", 94 | ":::::::::::::::: ::::::::::::::::", 95 | ":::::::::::::::: ::::::::::::::::", 96 | ":::::::::::::::: ::::::::::::::::", 97 | "'''':::::::::::: ::::::::::::::::", 98 | " '''':::: ::::::::::::::::", 99 | " ''''::::::::::::", 100 | " ''''::::"}, 101 | windows7 = { ' ,.=:!!t3Z3z., ', 102 | ' :tt:::tt333EE3 ', 103 | ' Et:::ztt33EEEL @Ee., ..,', 104 | ' ;tt:::tt333EE7 ;EEEEEEttttt33#', 105 | ' :Et:::zt333EEQ. $EEEEEttttt33QL', 106 | ' it::::tt333EEF @EEEEEEttttt33F ', 107 | ' ;3=*^```"*4EEV :EEEEEEttttt33@. ', 108 | ' ,.=::::!t=., ` @EEEEEEtttz33QF ', 109 | ' ;::::::::zt33) "4EEEtttji3P* ', 110 | ' :t::::::::tt33.:Z3z.. `` ,..g. ', 111 | ' i::::::::zt33F AEEEtttt::::ztF ', 112 | ' ;:::::::::t33V ;EEEttttt::::t3 ', 113 | ' E::::::::zt33L @EEEtttt::::z3F ', 114 | '{3=*^```"*4E3) ;EEEtttt:::::tZ` ', 115 | ' ` :EEEEtttt::::z7 ', 116 | ' "VEzjt:;;z>*` '}, 117 | none = { ""} 118 | } 119 | 120 | local colormaps = { 121 | windows8 = { 122 | {{1,33}},{{1,33}},{{1,33}},{{1,33}},{{1,33}},{{1,33}},{{1,33}}, 123 | {{1,33}},{{1,33}},{{1,33}},{{1,33}},{{1,33}},{{1,33}},{{1,33}}, 124 | {{1,33}},{{1,33}},{{1,33}} 125 | }, 126 | windows7 = { 127 | {{1,36}},{{1,36}},{{1,21},{2,15}},{{1,20},{2,16}},{{1,20},{2,16}}, 128 | {{1,19},{2,17}},{{1,18},{2,18}},{{4,16},{1,2},{2,18}},{{4,17},{2,19}}, 129 | {{4,17},{3,6},{2,4},{3,9}},{{4,16},{3,20}},{{4,15},{3,21}}, 130 | {{4,15},{3,21}},{{4,14},{3,22}},{{4,14},{3,22}},{{4,16},{3,20}}, 131 | }, 132 | none = { 133 | {{1,1}} 134 | } 135 | } 136 | 137 | local colornames = { 138 | windows8 = {"lightcyan"}, 139 | windows7 = {"red","green","yellow","blue"}, 140 | linux = {"yellow","lightblack","white"}, 141 | mac = {"green","yellow","lightred","red","magenta","blue"}, 142 | none = {} 143 | } 144 | 145 | local colors = { 146 | "black","red","green","yellow","magenta","blue","cyan","white" 147 | } 148 | 149 | 150 | 151 | 152 | 153 | 154 | local function getwmic(alias,key) 155 | for line in io.popen(("wmic %s get %s"):format(alias,key)):lines() do 156 | if not line:lower():match(key) then 157 | return (line:gsub("%s"," ")) 158 | end 159 | end 160 | end 161 | 162 | 163 | 164 | 165 | 166 | local ostype,depth = os.getenv("TERM") and "cygwin" or "windows" 167 | 168 | do 169 | -- Automatic color depth tests 170 | if ostype == "cygwin" then 171 | depth = "16" --os.getenv("TERM") == "cygwin" and "16" or "256" 172 | else 173 | depth = os.getenv("ANSICON") and "16" or "0" 174 | end 175 | end 176 | 177 | local reset = depth == "0" and "" or "\027[0m" 178 | 179 | local logo = getwmic("os","caption"):match("7") and "windows7" or "windows8" 180 | 181 | 182 | 183 | 184 | 185 | local function getcolor(x) 186 | if type(x) == "number" then 187 | return x < 16 and ( 188 | ("\027[%s;3%sm"):format(x<8 and 0 or 1,x%8) 189 | ) or ( 190 | ("\027[38;5;%sm"):format(x) 191 | ) 192 | elseif type(x) == "string" then 193 | for _,color in pairs(colors) do 194 | if x == color or x == "light"..color then 195 | return depth ~= "0" and ("\027[%s;3%sm"):format( 196 | (x:match("light") and 1 or 0), 197 | ({ 198 | ["black"]=0,["red"]=1,["green"]=2,["yellow"]=3, 199 | ["blue"]=4,["magenta"]=5,["cyan"]=6,["white"]=7 200 | })[(x:gsub("light",""))] 201 | ) or "" 202 | end 203 | end 204 | elseif x == nil then 205 | return "" 206 | end 207 | end 208 | 209 | 210 | 211 | 212 | 213 | do 214 | local flags = {{_,{}}} 215 | for i = 1,#arg do 216 | if arg[i]:sub(1,1) == "-" then 217 | table.insert(flags,{arg[i],{}}) 218 | else 219 | table.insert(flags[#flags][2],arg[i]) 220 | end 221 | end 222 | for _,args in pairs(flags) do 223 | if args[1] == "-h" or args[1] == "--help" then 224 | if args[2][1] == "color" then 225 | print((colorhelp:gsub("←","\027"))) 226 | elseif not args[2][1] then 227 | print(help) 228 | else 229 | print(("Invalid argument for %s: %s"):format(args[1],args[2])) 230 | end 231 | os.exit() 232 | elseif args[1] == "-0" or args[1] == "--nocolor" then 233 | depth = "0" 234 | elseif args[1] == "-1" or args[1] == "--18color" then 235 | depth = "16" 236 | elseif args[1] == "-2" or args[1] == "--256color" then 237 | depth = "256" 238 | elseif args[1] == "-l" or args[1] == "--logo" then 239 | if colornames[string.lower(args[2][1])] then 240 | logo = string.lower(args[2][1]) 241 | end 242 | elseif args[1] == "-v" or args[1] == "--vert" then 243 | if args[2][1] == "center" or args[2][1] == "top" or args[2][1] == "bottom" then 244 | options.vert = args[2][1] 245 | end 246 | elseif args[1] == "-c" or args[1] == "--color" then 247 | local args = table.concat(args[2]," ") 248 | if args:match(",") then 249 | for i,_ in pairs(colornames) do 250 | colornames[i] = {} 251 | end 252 | args = args:gsub("%s","") 253 | for color in args:gmatch("[^,]+") do 254 | color = tonumber(color) or color 255 | if getcolor(color) then 256 | for i,_ in pairs(colornames) do 257 | table.insert(colornames[i],color) 258 | end 259 | else 260 | print(("Invalid color: %s"):format(color)) 261 | os.exit() 262 | end 263 | end 264 | elseif args == "none" then 265 | for i,_ in pairs(colornames) do 266 | colornames[i] = {} 267 | end 268 | elseif args == "rainbow" then 269 | for i,_ in pairs(colornames) do 270 | colornames[i] = { 271 | "lightred","lightyellow","lightgreen","lightcyan", 272 | "lightblue","lightmagenta" 273 | } 274 | end 275 | else 276 | local done 277 | for _,color in pairs(colors) do 278 | if string.lower(args) == color then 279 | for i,_ in pairs(colornames) do 280 | colornames[i] = {color,"light"..color} 281 | end 282 | done = true 283 | end 284 | end 285 | if not done then 286 | print(("Invalid color: %s"):format(args)) 287 | os.exit() 288 | end 289 | end 290 | elseif args[1] == "-m" or args[1] == "--margin" then 291 | if (args[2][1] or ""):match("%d,%d") == args[2][1] and args[2][1] then 292 | local l,r = args[2][1]:match("(%d),(%d)") 293 | options.margins = {tonumber(l),tonumber(r)} 294 | else 295 | print(("Invalid margin format: %s"):format(args[2][1])) 296 | os.exit() 297 | end 298 | elseif args[1] == "-s" or args[1] == "--stripe" then 299 | local tab = {vertical=1,horizontal=2,none=0} 300 | if tab[args[2][1]] then 301 | options.stripe = tab[args[2][1]] 302 | else 303 | print(("Invalid stripe format: "):format(args[2][1])) 304 | os.exit() 305 | end 306 | elseif args[1] == "-b" or args[1] == "--block" then 307 | if tonumber(args[2][1]) and (tonumber(args[2][1]) or 0) > 0 then 308 | options.block = tonumber(args[2][1]) 309 | else 310 | print(("Invalid block format: "):format(args[2][1])) 311 | os.exit() 312 | end 313 | elseif args[1] == "-a" or args[1] == "--align" then 314 | options.align = not options.align 315 | elseif args[1] == "-L" or args[1] == "--lefty" then 316 | options.lefty = not options.lefty 317 | end 318 | end 319 | end 320 | 321 | 322 | 323 | 324 | 325 | local function caps(str) 326 | return string.upper(str:sub(1,1))..string.lower(str:sub(2)) 327 | end 328 | 329 | local function ctrim(str) 330 | return ((str or ""):gsub("\027%[[%d;]+m","")) 331 | end 332 | 333 | local function maplogo(logo) 334 | local len,out = logos[logo][1]:len(),{} 335 | for i,line in pairs(logos[logo]) do 336 | local d = 1 337 | for _,pair in pairs(colormaps[logo][i]) do 338 | local w = pair[2] 339 | local color = colornames[logo][pair[1]] 340 | if not color then 341 | local n,a = colornames[logo],pair[1] 342 | color = colornames[logo][a%#n == 0 and #n or a%#n] 343 | end 344 | out[i] = (out[i] or "")..getcolor(color)..line:sub(d,d+w-1) 345 | d = d + w 346 | end 347 | end 348 | return out 349 | end 350 | 351 | --11223344 352 | --abcdefgh 353 | 354 | local function stripelogo(logo) 355 | local stripe,block,log = options.stripe,options.block,logos[logo] 356 | local lc = colornames[logo] 357 | local out = {} 358 | if stripe == 1 then 359 | for x = 1,math.ceil(log[1]:len()/block) do 360 | for y = 1,#log do 361 | local color = getcolor(lc[x%#lc == 0 and #lc or x%#lc]) 362 | out[y] = (out[y] or "")..color..log[y]:sub(x*block-(block-1),x*block) 363 | end 364 | end 365 | elseif stripe == 2 then 366 | for y = 0,math.ceil(#log/block) do 367 | for yo = 1,block do 368 | local color = getcolor(lc[(y+1)%#lc == 0 and #lc or (y+1)%#lc]) 369 | if log[y*block+yo] then 370 | out[y*block+yo] = (out[y*block+yo] or "")..color..log[y*block+yo] 371 | end 372 | end 373 | end 374 | end 375 | return out 376 | end 377 | 378 | local function trim(str,len) 379 | return (str:len() <= len) and str or str:sub(0,len-3).."..." 380 | end 381 | 382 | local function colorscale(value,max) 383 | if depth == "256" then 384 | local scale = math.min(math.floor(value/(max/11))+1,11) 385 | return getcolor(16+math.min(scale-1,5)*36+math.min(11-scale,5)*6) 386 | elseif depth == "16" then 387 | return getcolor(({ 388 | "green","yellow","red" 389 | })[math.min(math.floor(value/(max/3))+1,3)]) 390 | else 391 | return "" 392 | end 393 | end 394 | 395 | local function bar(percent) 396 | local barwidth = math.floor(10*percent/100+0.5) 397 | return ("[%s%s%s%s]"):format( 398 | colorscale(percent,100),("="):rep(barwidth),reset, 399 | ("-"):rep(10-barwidth) 400 | ) 401 | end 402 | 403 | local function tn(...) 404 | local out = {...} 405 | for i,v in pairs(out) do out[i] = tonumber(v) end 406 | return unpack(out) 407 | end 408 | 409 | local function uptime() 410 | local lastBootUp = getwmic("os","lastbootuptime") 411 | local pattern="(%d%d%d%d)(%d%d)(%d%d)(%d%d)(%d%d)(%d%d)" 412 | local y,m,d,h,mi,s=tn((lastBootUp):match(pattern)) 413 | local up = {} 414 | up.days,up.hours,up.mins,up.secs = os.date("!%j %H %M %S",os.time()-os.time{ 415 | year=y,month=m,day=d,hour=h,minu=mi,sec=s 416 | }):match("(.+)%s(.+)%s(.+)%s(.+)") 417 | up.days = up.days - 1 418 | for a,b in pairs(up) do 419 | up[a] = tonumber(b) 420 | end 421 | return up 422 | end 423 | 424 | local function plural(n) 425 | return n ~= 1 and "s" or "" 426 | end 427 | 428 | local function getos() 429 | return getwmic("os","caption") 430 | end 431 | 432 | local function getkernel() 433 | return ostype == "windows" and ( 434 | os.getenv("OS").." "..getwmic("os","version") 435 | ) or ( 436 | io.popen("uname -sr"):read() 437 | ) 438 | end 439 | 440 | local function getname() 441 | local name = os.getenv(ostype == "cygwin" and "USER" or "USERNAME") 442 | local domain = os.getenv(ostype == "cygwin" and "HOSTNAME" or "USERDOMAIN") 443 | if depth == "256" then 444 | return ("\027[38;5;178m%s\027[1;37m@\027[38;5;240m%s"):format( 445 | name,domain..reset 446 | ) 447 | elseif depth == "16" then 448 | return ("\027[0;33m%s\027[0;37m@\027[0;30m%s"):format( 449 | name,domain..reset 450 | ) 451 | else 452 | return ("%s@%s"):format(name,domain) 453 | end 454 | end 455 | 456 | local function getfoobar() 457 | local foobar = socket.connect(fhost,fport) 458 | if foobar then 459 | local out 460 | repeat out = foobar:receive() until out:match("111") 461 | foobar:close() 462 | return out:match(".+|.+|.+|.+|.+|.+|(.+)|.+|.+|.+|.+|(.+)|") 463 | end 464 | end 465 | 466 | local function getmpd() 467 | local mpd = socket.connect(mhost,mport) 468 | if mpd then 469 | mpd:send("currentsong\r\n") 470 | local artist,track 471 | repeat 472 | local line,err = mpd:receive() 473 | local tag,value = line:match("(.-): (.+)") 474 | artist = artist or (tag == "Artist" and value) 475 | track = track or (tag == "Title" and value) 476 | until line == "OK" or line:match("ACK") or (not line) 477 | mpd:close() 478 | return artist,track 479 | end 480 | end 481 | 482 | local function getsong() 483 | if not socket then return "N/A - N/A" end 484 | foobar,mpd = {getfoobar()},{getmpd()} 485 | local artist = foobar[1] or mpd[1] or "N/A" 486 | local track = foobar[2] or mpd[2] or "N/A" 487 | return ("%s - %s"):format(artist,track) 488 | end 489 | 490 | local function getmemory() 491 | local ram = getwmic("os","totalvisiblememorysize") 492 | local freeram = getwmic("os","freephysicalmemory") 493 | local usedram = math.floor(((ram - freeram)/1024)+.5) 494 | local ram = math.floor((tonumber(ram)/1024)+.5) 495 | local percentage = math.floor((usedram/ram*100)*10+0.5)/10 496 | 497 | local width = (usedram..ram..percentage):len()+8 498 | local bar = bar(usedram/ram*100) 499 | local space = (" "):rep(24-width) 500 | 501 | local color = colorscale(usedram,ram) or "" 502 | local format = "%s%s%s/%s MB (%s%s%%%s) %s" 503 | 504 | return format:format(color,usedram,reset,ram,color,percentage,reset,space..bar) 505 | end 506 | 507 | local function getuptime() 508 | local uptime = uptime() 509 | local out = "%s day%s %s hour%s %s min%s %s second%s" 510 | local days,hours,mins,secs 511 | days,hours,mins,secs = uptime.days,uptime.hours,uptime.mins,uptime.secs 512 | return out:format( 513 | getcolor("lightwhite")..days..reset,plural(days), 514 | (colorscale(uptime.hours,24) or "")..hours..reset,plural(hours), 515 | (colorscale(uptime.mins,60) or "")..mins..reset,plural(mins), 516 | (colorscale(uptime.secs,60) or "")..secs..reset,plural(secs) 517 | ) 518 | end 519 | 520 | local function getspace() 521 | local space,out = io.popen("wmic logicaldisk get freespace,size"),{} 522 | local drives,max = {},0 523 | for line in space:lines() do 524 | if line:match("%d") then 525 | local freespace,size = line:match("(%d+)%s+(%d+)") 526 | local usedspace = size-freespace 527 | local total = math.floor(size/1024^3*10+0.5)/10 528 | local used = math.floor(usedspace/1024^3*10+0.5)/10 529 | local percent = math.floor(used/total*1000+0.5)/10 530 | local color = colorscale(used,total) or "" 531 | 532 | local width = (used..total..percent):len()+8 533 | local bar = bar(used/total*100) 534 | local space = (" "):rep(24-width) 535 | local format = "%s%s%s/%s GB (%s%s%%%s) %s" 536 | 537 | table.insert(out,format:format( 538 | color,used,reset,total,color,percent,reset,space..bar 539 | )) 540 | end 541 | end 542 | return unpack(out) 543 | end 544 | 545 | local function getcpu() 546 | for line in io.popen("wmic cpu get loadpercentage,name"):lines() do 547 | if line:match("%d") then 548 | local usage,name = line:match("(%d+)%s+(.+)") 549 | name = name:gsub("%s+"," "):gsub("%([RTM]+%)","") 550 | 551 | local color = colorscale(tonumber(usage),100) or "" 552 | local usage = tonumber(usage) 553 | local space,bar = (" "):rep(17-string.len(usage)),bar(usage) 554 | 555 | local format = "Usage: %s%s%%%s%s%s" 556 | return format:format(color,usage,reset,space,bar),name 557 | end 558 | end 559 | end 560 | 561 | local function getgpu() 562 | local gpu,gpulines = io.popen("wmic path Win32_VideoController get caption"),{} 563 | for line in gpu:lines() do 564 | if line and not line:lower():find("caption") and line:find("%w") then 565 | line = line:gsub("%(Microsoft Corporation %- WDDM 1%.0%)","") 566 | table.insert(gpulines,(line:gsub("%s+"," "):gsub("%([RTM]+%)",""))) 567 | end 568 | end 569 | return unpack(gpulines) 570 | end 571 | 572 | function getvs() 573 | local theme,dir1,dir2 574 | dir1 = [[HKCU\Software\Microsoft\Windows\CurrentVersion\ThemeManager]] 575 | dir2 = [[HKCU\Software\Microsoft\Windows\CurrentVersion\Themes]] 576 | local key = 'cmd /c "2>nul reg query '..dir1..' /v DllName"' 577 | for line in io.popen(key):lines() do 578 | if line:match("DllName") then 579 | return line:match("([^\\]+)%.msstyles") 580 | end 581 | end 582 | -- There isn't a visual style found 583 | -- This is often the case when using Windows Classic 584 | local key = 'cmd /c "2>nul reg query '..dir2..' /v CurrentTheme"' 585 | for line in io.popen(key):lines() do 586 | if line:match("CurrentTheme") then 587 | -- This is more difficult 588 | -- Reads the .theme file to determine the theme 589 | return caps(line:match("(%w+)%.theme")) 590 | end 591 | end 592 | end 593 | 594 | 595 | 596 | 597 | 598 | local format = { 599 | ["Name"] = getname, ["OS"] = getos, ["Uptime"] = getuptime, 600 | ["Kernel"] = getkernel, ["Now Playing"] = getsong, 601 | ["Memory"] = getmemory, ["Disk Space"] = getspace, ["CPU"] = getcpu, 602 | ["Visual Style"] = getvs, ["GPU"] = getgpu 603 | } 604 | 605 | 606 | 607 | 608 | 609 | local infocolor = colornames[logo][1] 610 | 611 | local information,info = {},{} 612 | 613 | for _,v in pairs(order) do 614 | table.insert(information,{v..":",{format[v]()}}) 615 | end 616 | 617 | if options.align then 618 | local longest = 0 619 | for _,l in pairs(order) do 620 | longest = math.max(longest,string.len(l)) 621 | end 622 | for _,v in pairs(information) do 623 | v[1] = (" "):rep((longest+1)-v[1]:len())..v[1] 624 | end 625 | end 626 | 627 | for _,e in pairs(information) do 628 | table.insert(info,getcolor(infocolor)..e[1]..reset.." "..e[2][1]) 629 | for i = 2,#e[2] do 630 | table.insert(info,(" "):rep(e[1]:len())..reset.." "..e[2][i]) 631 | end 632 | end 633 | 634 | local c1,c2 = _,info 635 | 636 | if options.stripe == 0 then 637 | c1 = maplogo(logo) 638 | else 639 | c1 = stripelogo(logo) 640 | end 641 | 642 | if options.lefty then 643 | c2,c1 = c1,c2 644 | local max = 0 645 | for i = 1,#c1 do 646 | max = math.max(max,ctrim(c1[i]):len()) 647 | end 648 | for i = 1,#c1 do 649 | c1[i] = c1[i]..(" "):rep(max-ctrim(c1[i]):len()) 650 | end 651 | end 652 | 653 | if options.vert ~= "top" then 654 | local unit 655 | if options.vert == "center" then 656 | unit = math.floor((math.max(#c1,#c2)-math.min(#c1,#c2))/2) 657 | elseif options.vert == "bottom" then 658 | unit = math.max(#c1,#c2)-math.min(#c1,#c2) 659 | end 660 | local smaller = ({[#c1]=c1,[#c2]=c2})[math.min(#c1,#c2)] 661 | if unit ~= 0 then 662 | for i = #smaller,1,-1 do 663 | smaller[i+unit] = smaller[i] 664 | smaller[i] = nil 665 | end 666 | end 667 | end 668 | 669 | for i = 1,math.max(#c1,#c2) do 670 | local m1,m2 = unpack(options.margins) 671 | m1,m2 = (" "):rep(m1),(" "):rep(m2) 672 | print(m1..(c1[i] or (" "):rep(ctrim(c1[#c1]):len()))..m2..(c2[i] or "")) 673 | end 674 | 675 | io.write("\027[0m") 676 | --------------------------------------------------------------------------------