Skip to content

Instantly share code, notes, and snippets.

@RYLSnmm
Created May 7, 2022 12:49
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save RYLSnmm/5170a488ca0f709f0a3c2533f2f2236c to your computer and use it in GitHub Desktop.
Save RYLSnmm/5170a488ca0f709f0a3c2533f2f2236c to your computer and use it in GitHub Desktop.
同じコマンドを履歴から 2 回実行してしまわないようにするためのツール
import std/os
import std/strutils
import std/sequtils
let log_file = getHomeDir() & DirSep & "once_log.txt"
type Parsed = object
action: string
param: string
exec: seq[string]
proc parse(): Parsed =
## コマンドライン引数のパース
let params = commandLineParams()
if params.len == 0:
Parsed(action:"help")
else:
let first = params[0]
if first == "-h" or first == "--history":
Parsed(action:"history")
elif first == "-a" or first == "--clear-all":
Parsed(action:"clear-all")
elif first == "-l" or first == "--clear-last":
Parsed(action:"clear-last")
elif first == "-i" or first == "--clear-id":
if params.len < 2:
Parsed(action:"help")
else:
Parsed(action:"clear-id", param:params[1])
elif first.startsWith("--clear-id="):
Parsed(action:"clear-id", param:first.split("=", 1)[1])
elif first.startsWith("-"):
Parsed(action:"help")
else:
Parsed(action:"exec", exec:params)
proc help() =
## ヘルプの表示
echo " once <command>"
echo " コマンドを実行します"
echo " 履歴ファイルに同じコマンドがある場合は実行されません"
echo " once --clear-all|-a"
echo " 履歴ファイルを削除します"
echo " once --clear-last|-l"
echo " 履歴ファイルから最後のエントリーを削除します"
echo " once --clear-id|-i <id>"
echo " 履歴ファイルから id を指定してエントリーを削除します"
echo " once --history|-h"
echo " 履歴ファイルの中身を id 付きで表示します"
echo " once"
echo " ヘルプ(これ)を表示します"
proc getHistoryLines(): seq[string] =
## 履歴ファイルを読み取って行の seq を返す
var lines: seq[string] = @[]
if fileExists(log_file):
let f = open(log_file)
defer: f.close
var line: string
while f.readLine(line):
if line != "":
lines.add(line)
lines
proc history() =
## 履歴を id 付きで表示
let lines = getHistoryLines()
if lines.len == 0:
echo "(empty)"
return
for i, line in lines:
echo $(i + 1) & " " & line
proc clearAll() =
## 履歴を全削除
if fileExists(log_file):
removeFile(log_file)
proc clearLast() =
## 履歴の最後を削除
var lines = getHistoryLines()
if lines.len > 0:
let removed = lines.pop
writeFile(log_file, lines.mapIt(it & "\n").join(""))
echo "Removed: ", removed
proc clearId(id: string) =
## id 指定で履歴から削除
var lines = getHistoryLines()
var line_index: int
try:
line_index = parseInt(id) - 1
except:
echo "Invalid id(parse): " & id
return
if 0 < line_index and line_index < lines.len:
let removed = lines[line_index]
lines.delete(line_index..line_index)
writeFile(log_file, lines.mapIt(it & "\n").join(""))
echo "Removed: ", removed
else:
echo "Invalid id(range): " & id
proc exec(command: seq[string]) =
## コマンドを実行
let cmd = quoteShellCommand(command)
discard execShellCmd(cmd)
proc requestExec(command: seq[string]) =
## 履歴をチェックして過去に実行してなければ実行
let lines = getHistoryLines()
let comm = command.join(" ")
let line_index = lines.find(comm)
if line_index < 0:
block:
let f = open(log_file, fmAppend)
defer: f.close
f.writeLine(comm)
exec(command)
else:
echo "Already executed id: " & $(line_index + 1)
proc main() =
let parsed = parse()
if parsed.action == "history":
history()
elif parsed.action == "clear-all":
clearAll()
elif parsed.action == "clear-last":
clearLast()
elif parsed.action == "clear-id":
clearId(parsed.param)
elif parsed.action == "help":
help()
elif parsed.action == "exec":
requestExec(parsed.exec)
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment