普通视图

发现新文章,点击刷新页面。
昨天以前wentao's blog

快速查找PowerShell的历史命令

2022年11月23日 19:41

bash 或者 fish 这些shell下面可以通过 history 来显示历史命令.在 PowerShell 下也可以通过 Get-History 来获取.

不过毕竟功能有点单一,写了个函数来扩展一下.

function hist {
$find = $args;
Get-Content (Get-PSReadlineOption).HistorySavePath | ? { $_ -like "*$find*" } | Get-Unique | more
}

这样就可以通过 hist 关键词 来搜索历史命令

如果你安装了 fzf 的话,可以使用如下的版本

function hist {
$find = $args;
Get-Content (Get-PSReadlineOption).HistorySavePath | ? { $_ -like "*$find*" } | Get-Unique | fzf
}

这样可以利用 fzf 的模糊查询来缩小范围.

denote

2022年11月20日 11:47

近期把笔记软件从Org-roam迁移到了Denote (denote.el),主要是有以下几个考虑:

  • org-roam在windows下面的性能堪忧,即使使用了emacs内置的sqlite性能还是不太行.
  • 酷炫的org-roam/org-roam-ui其实没啥用
  • denote性能和命名规范都挺合心意,

以下是我的配置:

(use-package denote
:bind
(("C-c n n" . denote)
("C-c n i" . denote-link-or-create)
("C-c n I" . denote-link)
("C-c n b" . denote-link-backlinks)
("C-c n a" . denote-add-front-matter)
("C-c n r" . denote-rename-file)
("C-c n R" . denote-rename-file-using-front-matter)
)
)
(setq denote-directory (expand-file-name "~/Org/notes/")
denote-known-keywords '("dev" "read" "report" "cslp")
denote-infer-keywords t
denote-sort-keywords t
denote-allow-multi-word-keywords t
denote-date-prompt-use-org-read-date t
denote-link-fontify-backlinks t
denote-front-matter-date-format 'org-timestamp
denote-prompts '(title keywords))
;; 在work目录下创建标签为work的笔记
(defun my-work-notes ()
"Create an entry tagged 'journal', while prompting for a title."
(interactive)
(denote
(denote--title-prompt)
'("work") 'denote-file-type '"./work"))

笔记查找使用的是mclear-tools/consult-notes: Use consult to search notes

(setq xref-search-program 'ripgrep)
(use-package consult-notes
:commands (consult-notes
consult-notes-search-in-all-notes
consult-notes-org-roam-find-node
consult-notes-org-roam-find-node-relation)
:config
(setq consult-notes-sources
'(
("notes" ?o "~/Org/notes")
))
:bind
( ("C-c n F" . consult-notes))
)
(use-package consult-denote
:bind
(
("C-c n f" . consult-denote))
)

参考资料

利用PowerShell来进行端口连通性测试

2022年7月17日 22:34

一般情况下在是使用 telnet 来做网络连通性的测试. PowerShell 也可以实现类似的功能.而且由于本身和 .Net 的关系,还可以通过 .Net 的支持来完成.

原生的方案:Test-Connection

连接成功

Measure-Command {Test-NetConnection wentao.org -Port 80} | % TotalSeconds

连接失败

Measure-Command {Test-NetConnection wentao.2org -Port 80} | % TotalSeconds

使用System.Net.Sockets.TcpClient的方案

 function Test-Port {
[CmdletBinding()]
param (
[Parameter(ValueFromPipeline = $true, HelpMessage = 'Could be suffixed by :Port')]
[String[]]$ComputerName,
[Parameter(HelpMessage = 'Will be ignored if the port is given in the param ComputerName')]
[Int]$Port = 5985,
[Parameter(HelpMessage = 'Timeout in millisecond. Increase the value if you want to test Internet resources.')]
[Int]$Timeout = 1000
)
begin {
$result = [System.Collections.ArrayList]::new()
}
process {
foreach ($originalComputerName in $ComputerName) {
$remoteInfo = $originalComputerName.Split(":")
if ($remoteInfo.count -eq 1) {
# In case $ComputerName in the form of 'host'
$remoteHostname = $originalComputerName
$remotePort = $Port
} elseif ($remoteInfo.count -eq 2) {
# In case $ComputerName in the form of 'host:port',
# we often get host and port to check in this form.
$remoteHostname = $remoteInfo[0]
$remotePort = $remoteInfo[1]
} else {
$msg = "Got unknown format for the parameter ComputerName: " `
+ "[$originalComputerName]. " `
+ "The allowed formats is [hostname] or [hostname:port]."
Write-Error $msg
return
}
$tcpClient = New-Object System.Net.Sockets.TcpClient
$portOpened = $tcpClient.ConnectAsync($remoteHostname, $remotePort).Wait($Timeout)
$null = $result.Add([PSCustomObject]@{
RemoteHostname = $remoteHostname
RemotePort = $remotePort
PortOpened = $portOpened
TimeoutInMillisecond = $Timeout
SourceHostname = $env:COMPUTERNAME
OriginalComputerName = $originalComputerName
})
}
}
end {
return $result
}
}

wezterm的workspace配置

2022年7月13日 21:19

wezterm里个特性是workspace,类似虚拟桌面的概念.可以在不同的workspace之间切换.这段时间工作上除了日常的开发以外,还有一些服务器的维护.这个时候这个workspace就会很方便.

另外可以根据 lua 来获取环境变量,来区分个人电脑、办公电脑做到能够一套配置多处使用.在 DUMMY 的机器上启动一个 Meta 的配置

if "DUMMY" == os.getenv("USERDOMAIN") then
local tab, pane, window = mux.spawn_window {
workspace = "Meta",
cwd = "d:/soft/Meta/",
}
pane:send_text(".\\meta.exe -d .\n")
end

官方有如下的一个配置示例.

local wezterm = require 'wezterm'
local mux = wezterm.mux
wezterm.on("gui-startup", function()
-- Set a workspace for coding on a current project
-- Top pane is for the editor, bottom pane is for the build tool
local project_dir = wezterm.home_dir .. "/wezterm"
local tab, build_pane, window = mux.spawn_window{
workspace="coding",
cwd=project_dir,
}
local editor_pane = build_pane:split{
direction="Top",
size=0.6,
cwd=project_dir
}
-- may as well kick off a build in that pane
build_pane:send_text("cargo build\n")
-- A workspace for interacting with a local machine that
-- runs some docker containners for home automation
local tab, pane, window = mux.spawn_window{
workspace="automation",
args={"ssh", "vault"},
}
-- We want to startup in the coding workspace
mux.set_active_workspace("coding")
end)
return {}

参考资料

读《万千微尘纷坠心田》

2022年5月28日 23:46

《万千微尘纷坠心田》的副标题是-文学阅读的生命化.讲我们应该如何读书、怎么从读书变成读进一本书.可以说是一本怎么讲吃书的一本书了.现在这个时代可能最不缺的就是书了,但是各类统计又在说读书的人少了.一方面获取咨询、知识的渠道多了.阅读不再是唯一的渠道了.

其中有一篇有如下的内容:

小说的创作,意味着我们从日常现实的领域纵身一跳,进入一个想象的生活的领域.想象并不意味着轻盈,一篇能够称之为好的小说,也绝不是任由想象的线索,安排词句和时间进行组合.

小说的阅读其实也是这样,读一些大部头小说的时候,了解当时的时空背景是很重要的.好的文字给人的带入感要远远高于视频的.读《战争与和平》,《飘》这些的时候,了解当时的历史背景对阅读会有很大的帮助.但是在一些科幻小说的时候,就可能不能这么做了.不过好的科幻小说,除了本身一个很重的概念一直支撑这整本小说.作者在构建整个环境的时候也会投入很多的笔墨.整体是自洽的这点很重要.

其中有篇讲了文本细读.这个其实用到编程中也是一样的.看别人写的代码,其实就跟读小说一样,有好有坏.但是如果真的代入进去,去发现他当时为什么这么写.看到代码之外的内容.和用户讨论需求的时候也是如此,透过讨论真正的看到他们内心想要的内容.

后面有篇分析石黑一雄的《远山深影》,又从另外一个角度理解了下这篇小说.

一个新的终端模拟器WezTerm

2022年5月15日 15:27

wezterm@wez利用Rust开发的一款终端模拟器.和microsoft/terminal还有 ITerm 类似.

支持的特性也特别多,比较有特色的是可以通过 lua 来配置或者增加一些特性.比方把 ~/.ssh/config 中的host直插入到 wezterm 中的 launch_menu ,在打开 launch_menu 的时候可以通过 / 来查找.

在快捷键支持这块有一个 leader key 的设定类似 vim 或者 emacs 里面的快捷键配置.

下面是鼓捣出来一个配置,如果有兴趣尝试的话可以试试看.把这个配置放到 ~/.config/wezterm/wezterm.lua 就可以了.

local function basename(s)
return string.gsub(s, "(.*[/\\])(.*)", "%2")
end
local wezterm = require "wezterm"
local SOLID_LEFT_ARROW = utf8.char(0xe0ba)
local SOLID_LEFT_MOST = utf8.char(0x2588)
local SOLID_RIGHT_ARROW = utf8.char(0xe0bc)
local ADMIN_ICON = utf8.char(0xf49c)
local CMD_ICON = utf8.char(0xe62a)
local NU_ICON = utf8.char(0xe7a8)
local PS_ICON = utf8.char(0xe70f)
local ELV_ICON = utf8.char(0xfc6f)
local WSL_ICON = utf8.char(0xf83c)
local YORI_ICON = utf8.char(0xf1d4)
local NYA_ICON = utf8.char(0xf61a)
local VIM_ICON = utf8.char(0xe62b)
local PAGER_ICON = utf8.char(0xf718)
local FUZZY_ICON = utf8.char(0xf0b0)
local HOURGLASS_ICON = utf8.char(0xf252)
local SUNGLASS_ICON = utf8.char(0xf9df)
local PYTHON_ICON = utf8.char(0xf820)
local NODE_ICON = utf8.char(0xe74e)
local DENO_ICON = utf8.char(0xe628)
local LAMBDA_ICON = utf8.char(0xfb26)
local SUP_IDX = {"¹","²","³","⁴","⁵","⁶","⁷","⁸","⁹","¹⁰",
"¹¹","¹²","¹³","¹⁴","¹⁵","¹⁶","¹⁷","¹⁸","¹⁹","²⁰"}
local SUB_IDX = {"₁","₂","₃","₄","₅","₆","₇","₈","₉","₁₀",
"₁₁","₁₂","₁₃","₁₄","₁₅","₁₆","₁₇","₁₈","₁₉","₂₀"}
local launch_menu = {}
local ssh_cmd = {"ssh"}
if wezterm.target_triple == "x86_64-pc-windows-msvc" then
ssh_cmd = {"powershell.exe", "ssh"}
table.insert(
launch_menu,
{
label = "PowerShell Core",
args = {"pwsh.exe", "-NoLogo"}
}
)
table.insert(
launch_menu,
{
label = "NyaGOS",
args = {"nyagos.exe", "--glob"},
}
)
end
local ssh_config_file = wezterm.home_dir .. "/.ssh/config"
local f = io.open(ssh_config_file)
if f then
local line = f:read("*l")
while line do
if line:find("Host ") == 1 then
local host = line:gsub("Host ", "")
table.insert(
launch_menu,
{
label = "SSH " .. host,
args = {"ssh", host}
}
)
end
line = f:read("*l")
end
f:close()
end
local mouse_bindings = {
{
event = {Down = {streak = 1, button = "Right"}},
mods = "NONE",
action = wezterm.action {PasteFrom = "Clipboard"}
},
-- Change the default click behavior so that it only selects
-- text and doesn't open hyperlinks
{
event = {Up = {streak = 1, button = "Left"}},
mods = "NONE",
action = wezterm.action {CompleteSelection = "PrimarySelection"}
},
-- and make CTRL-Click open hyperlinks
{
event = {Up = {streak = 1, button = "Left"}},
mods = "CTRL",
action = "OpenLinkAtMouseCursor"
}
}
wezterm.on("format-tab-title", function(tab, tabs, panes, config, hover, max_width)
local edge_background = "#121212"
local background = "#4E4E4E"
local foreground = "#1C1B19"
local dim_foreground = "#3A3A3A"
if tab.is_active then
background = "#FBB829"
foreground = "#1C1B19"
elseif hover then
background = "#FF8700"
foreground = "#1C1B19"
end
local edge_foreground = background
local process_name = tab.active_pane.foreground_process_name
local pane_title = tab.active_pane.title
local exec_name = basename(process_name):gsub("%.exe$", "")
local title_with_icon
if exec_name == "nu" then
title_with_icon = NU_ICON .. " NuShell"
elseif exec_name == "pwsh" then
title_with_icon = PS_ICON .. " PS"
elseif exec_name == "cmd" then
title_with_icon = CMD_ICON .. " CMD"
elseif exec_name == "elvish" then
title_with_icon = ELV_ICON .. " Elvish"
elseif exec_name == "wsl" or exec_name == "wslhost" then
title_with_icon = WSL_ICON .. " WSL"
elseif exec_name == "nyagos" then
title_with_icon = NYA_ICON .. " " .. pane_title:gsub(".*: (.+) %- .+", "%1")
elseif exec_name == "yori" then
title_with_icon = YORI_ICON .. " " .. pane_title:gsub(" %- Yori", "")
elseif exec_name == "nvim" then
title_with_icon = VIM_ICON .. pane_title:gsub("^(%S+)%s+(%d+/%d+) %- nvim", " %2 %1")
elseif exec_name == "bat" or exec_name == "less" or exec_name == "moar" then
title_with_icon = PAGER_ICON .. " " .. exec_name:upper()
elseif exec_name == "fzf" or exec_name == "hs" or exec_name == "peco" then
title_with_icon = FUZZY_ICON .. " " .. exec_name:upper()
elseif exec_name == "btm" or exec_name == "ntop" then
title_with_icon = SUNGLASS_ICON .. " " .. exec_name:upper()
elseif exec_name == "python" or exec_name == "hiss" then
title_with_icon = PYTHON_ICON .. " " .. exec_name
elseif exec_name == "node" then
title_with_icon = NODE_ICON .. " " .. exec_name:upper()
elseif exec_name == "deno" then
title_with_icon = DENO_ICON .. " " .. exec_name:upper()
elseif exec_name == "bb" or exec_name == "cmd-clj" or exec_name == "janet" or exec_name == "hy" then
title_with_icon = LAMBDA_ICON .. " " .. exec_name:gsub("bb", "Babashka"):gsub("cmd%-clj", "Clojure")
else
title_with_icon = HOURGLASS_ICON .. " " .. exec_name
end
if pane_title:match("^Administrator: ") then
title_with_icon = title_with_icon .. " " .. ADMIN_ICON
end
local left_arrow = SOLID_LEFT_ARROW
if tab.tab_index == 0 then
left_arrow = SOLID_LEFT_MOST
end
local id = SUB_IDX[tab.tab_index+1]
local pid = SUP_IDX[tab.active_pane.pane_index+1]
local title = " " .. wezterm.truncate_right(title_with_icon, max_width-6) .. " "
return {
{Attribute={Intensity="Bold"}},
{Background={Color=edge_background}},
{Foreground={Color=edge_foreground}},
{Text=left_arrow},
{Background={Color=background}},
{Foreground={Color=foreground}},
{Text=id},
{Text=title},
{Foreground={Color=dim_foreground}},
{Text=pid},
{Background={Color=edge_background}},
{Foreground={Color=edge_foreground}},
{Text=SOLID_RIGHT_ARROW},
{Attribute={Intensity="Normal"}},
}
end)
wezterm.on(
"update-right-status",
function(window)
local date = wezterm.strftime("%Y-%m-%d %H:%M:%S ")
window:set_right_status(
wezterm.format(
{
{Text = date}
}
)
)
end
)
local default_prog = {"pwsh.exe"}
return {
set_environment_variables = {
PATH = wezterm.executable_dir .. ";" .. os.getenv("PATH"),
},
window_frame = window_frame, -- needed only if using fancy tab
window_background_opacity = 0.8,
launch_menu = launch_menu,
mouse_bindings = mouse_bindings,
disable_default_key_bindings = true,
default_prog = default_prog,
font = wezterm.font("Fira Code"),
colors = {
tab_bar = {
background = TAB_BAR_BG,
},
},
text_background_opacity = 0.95,
leader = { key="x", mods = "CTRL"},
keys = {
{ key = "`", mods = "LEADER|CTRL", action=wezterm.action{SendString="`"}},
{ key = "v", mods = "CTRL", action=wezterm.action{PasteFrom = "Clipboard"}},
{ key = "-", mods = "LEADER", action=wezterm.action{SplitVertical={domain="CurrentPaneDomain"}}},
{ key = "\\",mods = "LEADER", action=wezterm.action{SplitHorizontal={domain="CurrentPaneDomain"}}},
{ key = "c", mods = "LEADER", action=wezterm.action{SpawnTab="CurrentPaneDomain"}},
{key="h",mods = "LEADER", action=wezterm.action{ActivatePaneDirection="Left"}},
{key="j", mods = "LEADER",action=wezterm.action{ActivatePaneDirection="Up"}},
{key="k", mods = "LEADER",action=wezterm.action{ActivatePaneDirection="Down"}},
{key="l", mods = "LEADER",action=wezterm.action{ActivatePaneDirection="Right"}},
{key = ",", mods = "LEADER", action = "ShowLauncher"},
{key = "b", mods = "LEADER", action = "ShowTabNavigator"},
{ key = "f", mods = "LEADER", action = "QuickSelect" },
{ key = "\t", mods = "LEADER", action="ActivateLastTab"},
{ key = "1", mods = "LEADER", action=wezterm.action{ActivateTab=0}},
{ key = "2", mods = "LEADER", action=wezterm.action{ActivateTab=1}},
{ key = "3", mods = "LEADER", action=wezterm.action{ActivateTab=2}},
{ key = "4", mods = "LEADER", action=wezterm.action{ActivateTab=3}},
{ key = "5", mods = "LEADER", action=wezterm.action{ActivateTab=4}},
{ key = "6", mods = "LEADER", action=wezterm.action{ActivateTab=5}},
{ key = "7", mods = "LEADER", action=wezterm.action{ActivateTab=6}},
{ key = "8", mods = "LEADER", action=wezterm.action{ActivateTab=7}},
{ key = "9", mods = "LEADER", action=wezterm.action{ActivateTab=8}},
-- { key = "l", mods = "LEADER", action=wezterm.action{EmitEvent="toggle-ligature"}},
{ key = "n", mods = "LEADER", action=wezterm.action{ActivateTabRelative=1}},
{ key = "p", mods = "LEADER", action=wezterm.action{ActivateTabRelative=-1}},
{ key = "&", mods = "LEADER|SHIFT", action=wezterm.action{CloseCurrentTab={confirm=true}}},
{ key = "x", mods = "LEADER", action=wezterm.action{CloseCurrentPane={confirm=true}}},
{ key = "w", mods = "ALT", action = wezterm.action({ CopyTo = "Clipboard" }) },
{ key = "y", mods = "CTRL", action = wezterm.action({ PasteFrom = "Clipboard" }) },
{ key = "Tab", mods = "LEADER", action = wezterm.action({ ActivateTabRelative = 1 }) },
},
}
❌
❌