使用 zinit 管理 zsh 插件

一直使用的 antigen 来管理 zsh 的插件,但是最近 zsh 加载因为加了一些插件变的非常慢,所以就像找找办法提速 zsh,在查询的过程中发现 antigen 已经很久没有更新,很多人推荐 antibody, 于是又试了一下 antibody, 不过在调研的过程中又发现了 zinit. 之后经过对比,发现 antibody 所谓的并行执行也没有提速很多,反而是名不见经传的 zinit 通过配置将加载时间稳稳的降低,在新建终端时几乎立即可见。

zinit

zinit 在众多的 zsh 插件管理工具中是一个比较小众的工具,但是因为其具备的 Turbo mode 可以显著的提升加载的速度。它通过在后台加载插件的方式提速。

配置

load light

可以使用 loadlight 来加载插件。

zinit load zdharma/history-search-multi-word
zinit light zsh-users/zsh-syntax-highlighting

说明:

  • load 加载的插件可以使用 zinit report 来查看加载过程
  • light 稍微比 load 快一些,但看不了 report

Oh My Zsh, Prezto

zinit 也可以加载 Oh My Zsh 和 Prezto 的插件,使用 snippet 关键字。snippet 会使用 wget, curl 等检测到的工具下载指定的单个文件。

zinit snippet 'https://github.com/robbyrussell/oh-my-zsh/raw/master/plugins/git/git.plugin.zsh'
zinit snippet 'https://github.com/sorin-ionescu/prezto/blob/master/modules/helper/init.zsh'

这两个工具比较常见,所以也可以使用内置的缩写:

zinit snippet OMZ::plugins/git/git.plugin.zsh
zinit snippet PZT::modules/helper/init.zsh

ice

使用 ice 的语句会作用于下一句 zinit 的定义。

zinit ice svn pick"init.zsh"
zinit snippet PZT::modules/git

比如加载了 PZT::modules/git 这个目录,但是 ice 中定义了 pick"init.zsh" , 那么就只会加载这个目录下的一个 init.zsh 文件。

as”program”

有些插件可能不是文件,而是需要加入到 $PATH 的一些命令,所以定义了 as 修饰符,和 “program”.

zinit ice as"program" cp"httpstat.sh -> httpstat" pick"httpstat"
zinit light b4b4r07/httpstat

上面的命令会把插件目录加入到 $PATH 中,然后将 httpstat.sh 拷贝到 httpstat 中并添加执行权限。

atpull

拷贝文件是一种安全的不影响更新的操作,原始的仓库没有修改,Git 不会有任何冲突。但是如果定义了合理的 atpull,也可以使用 mv

zinit ice as"program" mv"httpstat.sh -> httpstat" \
      pick"httpstat" atpull'!git reset --hard'
zinit light b4b4r07/httpstat

atpull 会在更新插件的时候执行,如果 atpull 以感叹号开始,表示会在 git pull 之前执行。

atpull, mv, cp 只会在有新的提交后执行。

如果用户使用 zinit update b4b4r07/httpstat 来更新插件,并且有新的提交被拉下来,那么

  • 首先 git reset --hard 执行,恢复原来的 httpstat.sh
  • 然后 git pull 执行,fast-forward 拉取最新的提交
  • 然后 mv 执行

Snippets completions

使用 as 关键字和 completion 可以将 snippet 的内容加入到 completion

zinit ice as"completion"
zinit snippet https://github.com/docker/cli/blob/master/contrib/completion/zsh/_docker

自动补全管理

Zinit 允许单独的禁用和启用每一个插件的自动补全。

zinit ice blockf
zinit light zsh-users/zsh-completions

可以通过 zi clist 查看插件提供的自动补全。

可以单独的启用和禁用补全:

$ zi cdisable cmake
Disabled cmake completion belonging to zsh-users/zsh-completions
$ zi cenable cmake
Enabled cmake completion belonging to zsh-users/zsh-completions

Turbo Mode

Zinit 可以使用 wait ice-mod 来延迟加载插件。Zsh 5.3 以后可以使用。

zinit 管理

zinit 升级

zinit self-update

升级其他插件

zinit update

清理没有加载的插件

zinit delete --clean

reference


2020-10-17 zsh , zinit , linux , terminal , antigen , plugin

阿里云函数计算中使用 Python psycopg2 访问 PostgreSQL

在之前的文章中提到过 函数计算 但一直没有正式的用起来,现在正好通过在阿里云函数计算中连接访问 PostgreSQL 来系统性的学习一下阿里云的函数计算。 首先要了解的几个概念:

  • Fun,Fun 命令是阿里提供的一个用于本地编译,部署函数计算的命令行工具,通过编写本地的 template.yml 配置文件可以对函数计算的服务, 方法, 网关 进行管理。更多内容可以参考官方提供的文档

Fun 命令简单使用

fun 命令的安装可以参考官方的文档.

配置 fun:

fun config

这里需要填写账号相关的信息。执行后会将账号相关的信息保存到:

`~/.fcli/config.yaml`

初始化项目模板:

fun init -n demo

fun 命令的执行依赖于 template.yml 配置文件。

本地调试:

fun local invoke

部署函数:

fun deploy

上传应用

上传应用方式:

  • 控制台
  • fun 工具

连接 PostgreSQL 数据库

项目依赖 template.yml 配置,配置函数计算的服务名,函数名,触发方式等等。

创建 Funfile 文件,安装依赖:

RUNTIME python3
RUN fun-install pip install psycopg2

然后执行 fun install

reference


2020-09-23 function-compute

Mac OS 上的平铺窗口管理工具 yabai

yabai 是一个 Mac OS 上的平铺窗口管理工具。Linux 上很早就有一系列的平铺窗口管理工具,比如 i3, awesome 等等。yabai 将这个功能带到了 Mac 上。所谓的平铺式窗口管理,是相较于普通的浮动窗口管理,在通常使用的情况下,系统上的应用如果打开了很多,就不可避免的相互叠加,需要频繁的使用 ⌘+Tab 来切换窗口。而平铺式窗口管理,则将所有的窗口平铺在桌面上,窗口之间不会相互重叠。

自定义快捷键完成窗口管理,比如最大化,调整大小,调整布局,切换桌面,移动到其他显示器等等 自动进行窗口布局 多桌面多显示器支持 高度的可订制化

安装

通过官网的教程 直接进行安装。

配置

yabai 的 wiki 已经解释了大部分的配置。

yabai 会自动加载 ~/.yabairc 配置文件。

配置的格式:

yabai -m <category> <command>

在配置调试阶段,不可避免的会需要多次加载 yabairc 配置,如果每次都要重启 brew services restart yabai 太慢了,yabai 提供了重新加载的方法,执行 :

launchctl kickstart -k "gui/${UID}/homebrew.mxcl.yabai"

也可以绑定快捷键

# e.g. bind to key in skhd:
# ctrl + alt + cmd - r : launchctl kickstart -k "gui/${UID}/homebrew.mxcl.yabai"

因为我自己的常用的快捷键是 hyper+r 重新加载 hammerspoon 的配置,所以改了一下 hyper+r 不仅重新加载 hammerspoon, 也重新加载 yabai.

Display

在显示器之间切换,显示器的编号可以在系统偏好中查看。

# Focus display focused before the current one (so you can alternate)
yabai -m display --focus recent

# Focus previous display by arrangement index
yabai -m display --focus prev

# Focus next display by arrangement index
yabai -m display --focus next

# Focus display with arrangement index 2
yabai -m display --focus 2

Space

将焦点放到不同的 Space 上

alt - 1 : yabai -m space --focus 1
alt - 2 : yabai -m space --focus 2
alt - 3 : yabai -m space --focus 3
alt - 4 : yabai -m space --focus 4

Windows

将光标定位到同一个 Space 的不同窗口上。

# focus window
alt - j : yabai -m window --focus south
alt - h : yabai -m window --focus west
alt - k : yabai -m window --focus north
alt - l : yabai -m window --focus east

交换窗口的位置

alt + shift - j : yabai -m window --swap south
alt + shift - h : yabai -m window --swap west
alt + shift - k : yabai -m window --swap north
alt + shift - l : yabai -m window --swap east

同样可以定义移动窗口

shift + cmd - h : yabai -m window --warp west
shift + cmd - j : yabai -m window --warp south
shift + cmd - k : yabai -m window --warp north
shift + cmd - l : yabai -m window --warp east

参考配置

reference


2020-09-17 mac , tiling-window-manager , window-manager , hammerspoon

You Quiz on the Block E70 世代差异

Covid-19 以来很少有让我继续追下去的韩综,除了带我入坑的周末综艺,一个 《[[Begin Again Korea]]》剩下的就只有《You Quiz On the Block》了。可以看得出来韩国的综艺人,电视人总还是带着一些社会关怀再做内容,之前在《Begin Again》里面就提过,在这个特殊的时代,他们把歌声第一时间先给一线的医护人员,公共服务人员,在这个疫情的特殊时期《Begin Again》就是一个治愈的存在,而相同的《You Quiz》第三期开篇就是对社会一线人员的致敬,公交司机,私营店老板,快递员,防疫人员,社会正是在这些人继续工作下去的时候才能维持正常的运行。

而在第三季的《You Quiz》中因为受到疫情影响,节目形式进行的改变,从原来街头的随机采访变成了主题式的室内采访,我甚至觉得这个模式似乎更有看点,主题也分外的明显,显而易见的比之前的模式要更加有中心主旨。虽然以前也会用一两个相同的问题来串起一个 Episode,但相较于现在而形式,也显得比较散。

再回到 E70,这一期的主题是世代差异。节目组分别邀请了 Z 世代,Y 世代,X 世代,386 世代,产业化世代 5 代人来讲述不同世代的故事。这一期的节目就像是一部倒放的韩国近代史。一直从 2000 年讲述到了上世纪 50,60 年代,当然叙事的方式并不是大而全的通用叙事,而是更加具体的从个人视角发出的主观的历史叙事。我作为千禧一代 (Y 世代)出生的人,最感同身受的却是 X 世代,或许另一个角度也能看出两个国家发展阶段的不同。

另外一个能察觉到节目组用心之处的便是节目的音乐,虽然韩综的配乐一直是长项,但这样的一个主题下,便更能体现其年代感,每一个世代所接触到的音乐,所关心的音乐人都不一样。生活在 2000 年以后 Z 世代是随手可得的音乐,Y 世代是放在自己的网络小屋的背景音乐,是自己的在庆典上偶像的歌曲,在到 X 世代是弘大,是夜店的歌曲,386 世代而言,音乐要珍贵许多,要守在广播前等待自己喜欢的歌手出现,再用录音机把歌声录下(杨熙恩,宋昌植)(采访的对象提到的杨熙恩 양희은 也是我非常喜欢的一位歌手,在 [[Fantastic Duo]] 短暂出现过),到更早一代,只能在异国他乡独自一人的晚上收听唯一的一档韩语广播。每一个世代都有自己喜欢的音乐,而有些音乐不像那个时代被一代人熟知,也依然可以穿过时间,直达现在每一个观众的内心,尤其是看那位远赴德国务工的老爷爷哼唱出《阳光明媚的日子 (해뜰날 by 송대관)》:

꿈을안고왔단다 抱着梦想来了 내가왔단다 我来了 슬픔도괴로움도 悲伤与伤心 모두모두비켜라 统统都让开 안 뒤는 일이없단다 有志者 노력하면은 事竟成 쨍하고해뜰날 阳光明媚的日子 고구간단다 回到故国 쨍하고해뜰날 阳光明媚的日子 고구간단다 回到故国

这几句歌词出来,直抵人心。音乐无论在哪个年代,虽然会以不一样的形式出现,虽然会被不一样的歌手所演绎,但总能给人以慰藉,这或许也是我独爱《Begin Again》的理由吧。

抛开音乐回到这几代人对历史时刻的最深记忆,而这些历史事件也逐渐的塑造了如今的韩国。从远到近说起。

  • 1963 年后陆续派遣近两万名劳工赴德国务工,电影 [[国际市场]] 中有讲述
  • 朴正熙政权在 1961 年至 1979 举国之力发展工农业,史称「汉江奇迹」,1979 年 10 月 26 日,朴正熙被中央情报部部長金载圭暗杀,电影 [[南山的部长们]] 有讲述,另 [[孝子洞理发师]] 1
  • 1980 年 5.18 光州民主化运动 [[出租车司机]] [[华丽的假期]] [[薄荷塘]]
  • 1987 年 6 月民主抗争,朴种哲事件,李韩烈事件 [[1987 黎明到来的一天』]
  • 1994 年 [[圣水大桥倒塌事件]] 电影 [[蜂鸟]] 中有提及
  • 1995 年 6 月 29 日 [[三丰百货大楼崩塌事故]],502 人死亡,6 人失踪,937 人受伤
  • 1997 年 12 月 3 日,向 [[IMF 申请金融救济』] 电影 [[国家破产之日]] 讲述的就是这一段历史
  • 2014 年 [[世越号事件]],已经有无数的电影来铭记这件事情 [[潜水钟]] [[那天,大海]]

大多数的历史性事件已经有大量的电影,进行了更加详细的记录和阐述。而现在的采访才更加有价值,事件的亲历者,亲自讲述那段苦难,虽然现在能笑着说出来,但背后却不知道隐藏了多少泪水。赴德国的老爷爷讲述第一次面试举麻袋失败后在家练习,亲历 1987 年 6 月运动后讲述为后辈捡起掉落的鞋子,却不料是最后一别。不禁让我感慨现实有的时候远比电影要残酷。老爷爷最后回答人生是什么的时候说,「人生是艺术」,不为过,也确确实实可以形容了。

Z 世代

  • 2000 年后出生,现在 10 代的青少年们
  • 不看文本,看视频
  • 不用电脑,用手机
  • 产品的生产者与消费者
  • 在数字环境下成长的数字原住民

唠叨会让人不爽,忠告会让人更不爽。

Y 世代

  • 又被称为千禧一代,指 1980 年代和 1990 年代出生的人
  • 2014 年世越号事件

X 世代

X 世代

  • 是指出生与 1960 年代后期到 1970 年代之间
  • 在人类历史上唯一同时经历过数字和模拟的一代人
  • 拒绝老一代的习俗和秩序,用全身拒绝已存在的条条框框,个性分明的一代人
  • 享受了 90 年代经济上升,生活富足的第一代人

经历事件:

  • 1994 年 [[圣水大桥倒塌事件]] 电影 [[蜂鸟]] 中有提及
  • 1995 年 6 月 29 日 [[三丰百货大楼崩塌事故]],502 人死亡,6 人失踪,937 人受伤
  • 1997 年 12 月 3 日,向 [[IMF 申请金融救济』] 电影 [[国家破产之日]] 讲述的就是这一段历史

386 世代

386 世代是在 60 年代出生,在 80 年代上大学,在 90 年代是 30 多岁的世代。当时的电脑架构是 386,还是 486 的,还是奔腾的,这个时候登场的 386 世代。这是一个象征着当时主导抵抗军事政权的学生运动和工人运动等社会运动的世代。

[[柳烈的音乐专辑]] 中

电影 [[1987 黎明到来的一天』] 中有大量描述。

产业化世代

1945 年光复之后,韩国战争期间出生的世代。1960~1970 年代,游走世界,掀起产业发展,创造出「汉江奇迹」,大韩民国经济成长的主力,称之为「产业化世代」。 电影 [[国际市场]] 有讲述。

  1. https://en.wikipedia.org/wiki/Miracle_on_the_Han_River 


2020-09-05 thinking

使用 Goku 配置 Karabiner

Karabiner 是 MacOS 上一款强大的自定义键盘的软件,可以非常自由的定义任何键位。

之前看文章是将 Caps Lock 作为一个 Hyper key,但看过 @nikitavoloboev 的文章之后,发现利用 Karabiner 和 Goku 定义的 DSL 配置语言可以更加充分的发挥 Karabiner 的功能。

Karabiner Elements 使用 JSON 作为配置规则的格式。使用 JSON 作为 Karabiner 配置格式的问题在于,这种格式非常庞大,在生成之后几乎很难徒手去做修改,对于复杂的配置可能长达几万行。

前提知识

Sticky keys

Sticky Keys 叫做粘滞键,是方便无法同时按下 Ctrl C 这样组合按键的用户,启用粘滞键后按下任何 modifier 按键后,这个 modifier 按键会持续激活直到按下一个非 modifier 按键。

Modifier key

常见的 modifer 按键有 Ctr, Command, Shift, Alt, Option,Fn, Caps Lock 等等。

A keyboard feature that enables you to press a modifier key (CTRL, ALT, or SHIFT), or the Windows logo key, and have it remain active until a non-modifier key is pressed. This is useful for people who have difficulty pressing two keys simultaneously.

其他可作为 modifier key 的按键有:

  • \
  • ,
  • .
  • space
  • Tab

EDN

EDN 全称是 「extensible data notation」,下面是一个最基本的 EDN:

{:main [
  {:des "hello world"
   ; comments use semicolons
       :rules [
      [:a :b] ; map a key to b key
   ]}
]}

不用担心这里看不明白,后面会继续展开。

什么是 Karabiner

Karabiner 是一个 MacOS 上的键盘自定义工具。

定义第一个 Hyper key

准备工作:

  • 下载 Karabiner Elements
  • 安装 Goku (Karabiner DSL) brew install yqrashawn/goku/goku
  • 执行 goku 服务,让修改立即生效 brew services start goku
  • 打开 Karabiner
  • 然后在 ~/.config/ 目录下创建 karabiner.edn 文件,可以参考我的
  • 然后可以参考教程 开始自己的配置编写啦

Goku 会通过 EDN 文件生成 karabiner.json,编写好 edn 文件后可以执行 goku 来生成 JSON 配置。

基本使用

整个 EDN 配置可以分成几个部分

  • 定义主要的 profile 及基本信息
  • 预置的条件
  • main 主要的键映射配置

接下来就一步步看一下最简单的配置。

从最主要的 main 部分配置来看。

{:main[ {:des "..." :rules [[<from> <to> <condition>]]}
        {:des "..." :rules [[<from> <to>]
                            [<from> <to>]]} ]}
  • 花括号内整个内容表示一个规则
  • :des 用来注释
  • :rules 中是真正的规则
  • 规则又分成 from, to, condition,其中 condition 部分是可选的。

预置条件

定义应用

比如定义应用程序,可以使用 bundle ID

:applications {:chrome ["^com\\.google\\.Chrome$"]}

定义设备

定义设备:

:devices {:quickfire [{:vendor_id 1234 :product_id 17}]}

定义输入法

定义输入法:

 :input-sources {:squirrel {:input_mode_id "com.googlecode.rimeime.inputmethod.Squirrel"
              :input_source_id "com.googlecode.rimeime.inputmethod.Squirrel.Rime"
              :language "zh-Hans"}
             :us {:input_mode_id ""
                  :input_source_id "com.apple.keylayout.US"
                  :language "en"}}

变量条件定义:

    [:escape [:escape ["in-alfred" 0]] ["in-alfred" 1]]
;;   |<from>||_________<to>__________| |<conditions> |

这个规则表示的含义是,当变量 in-alfred 等于 1 时,tap Escape 按键映射到 Escape 并将 in-alfred 变量设置为 0 。

在使用条件的时候可以组合使用,或者使用非语句。

比如

{:applications {:chrome ["^com\\.google\\.Chrome$"]
                :safari ["^com\\.apple\\.Safari$"]}
 :main [{:des "a to 1 only in chrome" :rules [[:a :1 :chrome]]}
        {:des "a to 1 only in chrome, safari" :rules [[:a :1 [:chrome :safari]]]}
        {:des "a to 1 only outside chrome, safari" :rules [[:a :1 [:!chrome :!safari]]]}]}

或者组合使用

:main [{:des "a to 1 multiple conditions"
        :rules [[:a :1 [:chromes :quickfire :us]]]}]}

这条规则就表示在 Google Chrome 中,使用外置的 quickfire 键盘,并且输入法是 us 时,将 a 键映射到 1。

组合规则

简单规则,一个键映射到另一个按键,一个键映射到多个按键

{:main [{:des "a to 1" :rules [[:a :1]]}
        {:des "b to 2" :rules [[:b :2]]}
        {:des "c to insert 123" :rules [[:c [:1 :2 :3]]]}]}

多个按键映射到其他按键

:rules [[:j :l] :f20]

配置也可以将按键映射到 Shell 脚本

:rules [{:des "hyper 1 to clean tmp"
                   :rules [[:!!1 ["rm -rf /tmp/*"]]]]}

对于常见的修饰键 modifier,Goku 中用简化的配置来表示

    ;; !  | means mandatory -   modifier(s) alone when pressend change behavior
    ;; #  | means optional  -   modifiers are optional (but atleast one necessary)

    ;; :!Ca is keycode :a and prefix a with !C

    ;; C  | left_command
    ;; T  | left_control
    ;; O  | left_option
    ;; S  | left_shift
    ;; F  | fn
    ;; Q  | right_command
    ;; W  | right_control
    ;; E  | right_option
    ;; R  | right_shift

    ;; ## | optional any
    ;; !! | command + control + optional + shift (hyper)

说明:

  • 在不设置 mofifiers 时,键映射只有在没有 modifier 时才生效,比如定义了一条规则,将 Caps Lock 映射成 Escape,那么只有在单独按下 Caps Lock 的时候才会映射成 Escape,如果组合按键比如 Left Shift+Caps Lock(当然应该没人那么做) 的时候,表现还是 Left Shift+Caps Lock
  • 当 modifier 为 mandatory 时,只有 modifier 按下时,映射才会触发

定义模板

{:templates {:launch "osascript -e 'tell application \"Alfred 3\" to run trigger \"launch %s\" in workflow \"yqrashawn.workflow.launcher\" with argument \"\"'"}
 :main [{:des "launcher mode"
         :rules [[:k [:launch "Emacs"] :launch-mode]
                 [:l [:launch "Chrome"] :launch-mode]
                 [:m [:launch "Mail"] :launch-mode]
                 [:v [:launch "WeChat"] :launch-mode]]}]}

simlayer

定义 simlayer

:simlayers {:vi-mode {:key :d}}

上面的规则定义了如果按下了 d 按键,则设置变量 vi-mode 为 1,表示进入 simlayer vi-mode,to_if_alone dto_after_key_up 然后设置变量 vi-mode 到 0 。

配置样例

交换 Left Option 和 Left Command

当我使用外置键盘的时候交换 Option 和 Command 的按键。

首先定义一些设备:

 :devices {
    :apple [{:vendor_id 1452 :product_id 832}]
    :quickfire [{:vendor_id 9494 :product_id 17}]
  }

特定键盘更改键位,改完之后就可以和内置键盘的键位一样了,不用去熟悉两套键盘了。

可以使用两种不同的方式进行配置:

这里的 quickfire 是我的外接键盘。这些信息可以在 Karabiner 提供的 EventViewer 中查看。

然后在 main 部分定义:

        {:des "swap cmd <-> option when using specific devices"
         :rules [
                 [:##left_command :left_option [:quickfire]]
                 [:##left_option :left_command [:quickfire]]
                 ] }

或者

    {:des "CM Storm keyboard setup"
     :rules [:quickfire
                 [:##left_command :left_option]
                 [:##left_option :left_command]
             ]}

Caps lock

tap caps lock once -> Escape key
hold caps lock -> hold Ctrl+Shift+Option+Command at same time

Left Shift/Right Shift

在英文的世界中,有一种 Remap,是将

left_shift once -> type (
right_shift once -> type )

但是在中文的世界里面,我的 Shift 是作为中英文切换按键,非常重要的一个按键。

O 模式

如果经常在几个常见的应用之间切换,即使用了不错的比如 Context 这样的窗口管理工具,那也会在 Command + Tab 按键中非常频繁的按键。假如有方式可以通过按下键盘上的快捷键就可以直接切换到不同的窗口,是不是可以省去不少的烦恼。

下面是一个模式,通过按住 O,然后快速按下第二个按键就可以实现在常用的应用之间切换。

hold o + tap i -> launch "iTerm"
hold o + tap c -> launch "Chrome"
hold o + tap b -> launch "Obsidian"
tap o  -> type "o"

记住一定要按住 o 不要松开然后再按 c 就可以快速切换到 Chrome。 一旦熟悉了自己的配置,就会发现再也不需要使用 Cmd + Tab 来切换了。

将 Caps Lock 作为 Command+Control+Option+Shift 同时按下的效果

        {:des "caps lock -> escape(alone) and caps lock -> hyper"
         :rules [
                 [:##caps_lock :!CTOleft_shift nil {:alone :escape}]
                 ]}

Ctrl+np 作为上下

        {:des "Ctrl np -> down up"
         :rules [
                 [:!Tn :down_arrow [:ctrlnp]]
                 [:!Tp :up_arrow [:ctrlnp]]
                 ]}

禁用 Cmd+H 隐藏

        {:des "Disable Cmd+H Hide"
         :rules [
                 [:!Ch nil nil [:kybs]]
                 ]}

按住 Cmd+q 退出应用

        {:des "Cmd + Q held 1 second to quit"
         :rules [
                 [:!Cq nil nil {:held :!Cq }]]}

Cheatsheet

    ;; !  | means mandatory -   modifier(s) alone when pressend change behavior
    ;; #  | means optional  -   modifiers are optional (but atleast one necessary)

    ;; :!Ca is keycode :a and prefix a with !C

    ;; C  | left_command
    ;; T  | left_control
    ;; O  | left_option
    ;; S  | left_shift
    ;; F  | fn
    ;; Q  | right_command
    ;; W  | right_control
    ;; E  | right_option
    ;; R  | right_shift

    ;; ## | optional any
    ;; !! | command + control + optional + shift (hyper)

    ;; to understand better how modifiers work in karabiner
    ;; karabiner definition of mandatory and optional
    ;; https://karabiner-elements.pqrs.org/docs/json/complex-modifications-manipulator-definition/from/modifiers/


    ;; need to prefix C T O S F with ! or #
    ;;
    ;; code for all this:
    ;; https://github.com/yqrashawn/GokuRakuJoudo/blob/b9b334a187379f9bc8182ad59e2cca2a1789e9c0/src/karabiner_configurator/keys.clj#L68

更多

  • 阅读 Nikita Voloboev 的博客
  • 完整的尝试官方提供的例子
  • 然后在仔细的读一读上面的例子

reference

其他配置案例:


2020-08-20 karabiner , mac , goku , edn , config

使用 dotbot 管理 dotfiles 配置文件

一直都使用手动的方式来管理 dotfiles,之前一方面是学习,一方面是熟悉整个配置,但随着配置文件的不断增多,管理便成为了一个问题。今天本来是在看 Karabiner 的配置,然后找到了一些参考,发现 narze 使用 dotbot 来管理其配置。便顺手也把我的 dotfiles 改了一下。

Dotbot 的原理非常简单,就是将配置文件软连接到特定的位置,使得 Vim,Tmux, zsh 之类可以读取。然后 Dotbot 用自己的定义的一套配置格式将整个过程简化。使得最后可以直接运行 git clone $git@github.com:einverne/dotfiles.git && cd dotfiles && ./install 一键完成初始化。

使用

最基本的使用方法,参考说明:

cd ~/.dotfiles # replace with the path to your dotfiles
git init # initialize repository if needed
git submodule add https://github.com/anishathalye/dotbot
git config -f .gitmodules submodule.dotbot.ignore dirty # ignore dirty commits in the submodule
cp dotbot/tools/git-submodule/install .
touch install.conf.yaml

将其加入为作为 submodule 然后添加一个配置 install.conf.yaml 即可。

Configuration

配置文件是 yaml 格式,非常易读。这是官网给的一个例子:

- defaults:
    link:
      relink: true

- clean: ['~']

- link:
    ~/.tmux.conf: tmux.conf
    ~/.vim: vim
    ~/.vimrc: vimrc

- create:
    - ~/downloads
    - ~/.vim/undo-history

- shell:
  - [git submodule update --init --recursive, Installing submodules]

目前 Dotbot 定义了一系常用的动作,比如 link, create, shell, clean 等等。

defaults

defaults 定义了默认的行为。

link 命令定义了文件或文件夹如何 symbolically linked。

create

create 命令定义了回去创建这些目录。

shell

Shell 命令则会指定需要运行的命令。

clean

clean 命令会去检查目录下的连接,如果发现连接已经无效则会移除这些连接。

reference


2020-08-15 dotfiles , config , mac , linux , vim , zsh

使用 assh 来管理 SSH config

前两天一直在思考如何管理我的 SSH config 配置,最后的解决办法就是通过 git 版本管理起来。但这两天由冒出一个新的问题,那就是经常在国内直连 aws 或者 oracle 的机器时 ssh 连不上,但是通过国内的 VPS 中转就非常快,那这就意味着,我每一次连接国外的机器时必须先登录腾讯云的机器,然后在从腾讯云的机器上连过去,有些麻烦,但那天在 Twitter 上看到有人分享了一个 SSH 管理的命令行工具 assh,大致的看了一下使用简介,通过配置就可以完美的解决这个问题。

ProxyCommand

assh 这个工具就将登录一台机器跳转 SSH 再登录另外一台机器的步骤简化了,assh 使用 lib-ssh 提供的 ProxyCommand 来实现。大部分的公司,或者注重安全的 SSH 访问都会将 SSH 的登录配置管理放到一台堡垒机或者跳板机上,然后通过跳板机再去连接真正的机器。

 +-------+       +----------+      +-----------+
 | Laptop| <---> | Jumphost | <--> | RealServer |
 +-------+       +----------+      +-----------+

比如上面的流程中,可能需要先连接 Jumphost:

ssh -p 222 someone@Jumphost

然后在 Jumphost 上连接 RealServer:

ssh someone@RealServer

如果要简化这个步骤可以使用 SSH 的 -J 选项:

ssh -J someone@Jumphost:222 someone@RealServer

或者可以使用 ProxyCommand:

ssh -o ProxyCommand='ssh -W %h:%p -p 222 someone@Jumphost' someone@RealServer

从 OpenSSH 7.3 开始,还可以使用 ProxyJump,可以通过在 config 文件中配置:

Host RealServer
    HostName 1.2.3.4
	ProxyJump someone@Jumphost:22[, user2@Jumphost2:222]
	User someone

如果有多个 Jumphost 可以直接用逗号分隔接在后面。

上面两个方式都可以直接通过 Jumphost 来直接登录到 RealServer 上。

SSH Config 配置

  • Host: 定义 host, * 可以用来表示全局配置
  • HostName: 定义真实的 hostname, 可以是域名或者 IP
  • User: SSH 登录的用户名
  • IdentityFile: 私钥路径
  • ProxyCommand: 定义连接服务器的命令
  • LocalForward: 通过 TCP 转发指定的本地端口到远程的端口
  • Port: 指定连接的远程端口
  • Protocol: 协议
  • ServerAliveInterval: 设置没有数据后多少时间间隔超时
  • ServerAliveCountMax: 设置服务活跃信息的数量,如果阈值达到,同时服务器活跃信息 ,服务器活跃消息 (server alive messages) 通过加密通道传输,因此不能被欺骗。The TCP keepalive 选项通过 TCPKeepAlive 是可以伪造的。服务器活跃机制在判断客户端或者服务器在不活跃时何时断开是非常有用的。默认值是 3,举一个例子,ServerAliveInterval 设置成 15,ServerAliveCountMax 保持默认,如果服务器没有回应,ssh 会在大约 45 秒后断开连接。这个选项只在 protocol 2 下有效

看一个最基本的 assh.yml 配置:

hosts:
  hosta:
    Hostname: 1.2.3.4

  hostb:
    Hostname: 5.6.7.8
    Gateways: hosta

  hostc:
    Hostname: 9.10.11.12
    Gateways: hostb

  hostd:
    Hostname: 13.14.15.16
    GatewayConnectTimeout: 2
    Gateways:
    - direct
    - hosta

说明:

  • 配置了 hosta 直连
  • hostb 则是通过 hosta 连接,ssh hostb 时会转换成 ssh -o ProxyCommand="ssh hostb nc %h %p" hosta
  • hostc 通过 hostb 连接
  • hostd 会首先尝试直连,如果失败了则回退到使用 hosta 连接

加速 SSH 会话

OpenSSH 可以复用存在的 TCP 连接,比如在创建了多个 SSH sessions 的时候,可以避免 TCP 创建连接带来的过度开销,修改 vi ~/.ssh/config:

Host *
	ServerAliveInterval 60
	ServerAliveCountMax 30
	ControlMaster auto
	ControlPath ~/.ssh/connection-%r@%h:%p
	ControlPersist 48h

assh

回到 assh 本身,assh 是用 Go 语言编写的一个命令行工具,使用 yaml 格式的配置,可以通过该配置快速生成 ~/.ssh/config 配置,通过几行配置就可以利用 ProxyCommand 来进行 SSH 跳转。

特性

assh 非常小巧,当却很强大

  • 支持正则表达式
  • 支持别名 aliases -> gate.domain.tld
  • 支持 includes 语法,可以将配置文件拆分到多个文件 includes: split configuration in multiple files
  • 支持 SSH 连接的透明转发 gateways -> transparent ssh connection chaining
  • local command execution: finally the reverse of RemoteCommand
  • inheritance: make hosts inherits from host hosts or templates
  • 支持继承,可以通过继承其他 hosts 或者模板来简化配置
  • templates: 模板
  • 通过环境变量来进行配置 variable expansion: resolve variables from the environment
  • 更加灵活的 ProxyCommand, smart proxycommand 当 netcat 或者 socat 可用时,会替换纯 TCP 连接
  • 可以进行速率控制,rate limit
  • JSON output
  • desktop notifications: based on events
  • Graphviz representation of the hosts

Install

go get -u moul.io/assh/v2

Event

assh 支持一些事件,可以用来触发一些操作或者进行通知。

BeforeConnect

BeforeConnect 会在 assh 将要连接到远程 SSH 端口时触发。

OnConnect

OnConnect 会在连接到远端 SSH 端口后被调用。

OnConnectError

OnConnectError 会在 assh 在建立 TCP 连接失败时调用。

OnDisconnect

OnDisconnect 会在 assh socket 断掉后触发。

BeforeConfigWrite

BeforeConfigWrite 会在 assh 重写 ~/.ssh/config 时触发。

基础命令

assh config

# 生成 SSH 配置文件
assh config build
assh config build > ~/.ssh/config
# 搜索 hosts
assh config search <keywords>

# 列出配置
assh config list
# 可视化显示
assh config graphviz

assh sockets

# 列出活跃的连接
assh sockets list
# create a master control sockets
assh sockets master
# close active control sockets
assh sockets flush

assh ping

# send packets to the SSH server
assh ping -c 4 host

reference


2020-07-28 ssh , assh , ssh-config , ssh-manage , config-management

备份和恢复从 Chrome Webstore 中下架的 Google Chrome Extension

这两天重装系统同步 Chrome 的数据才发现,我一直使用的 Dream Afar New Tab 这个我用了很久的扩展从 Chrome Webstore 消失了,不清楚是 Google 主动下架,还是作者很久没有更新被 Webstore 下了还是为什么。但这个扩展经过了很多的 Chrome 版本依然运行良好至今为止都能每天给我提供世界不同地方的美景。

备份文件

Chrome 的扩展安装后以文件的形式在如下的目录中:

  • Windows: %UserProfile%\AppData\Local\Google\Chrome\User Data\Default\Extensions
  • Linux: ~/.config/google-chrome/Default/Extensions/
  • Mac: ~/Library/Application Support/Google/Chrome/Default/Extensions/

然后在 chrome://extensions/ 扩展管理中点击 Details 获取扩展的详细信息可以知道扩展的唯一 ID,这个 ID 一般也是 Chrome Web Store 的唯一索引 ID,比如 Dream Afar 是 henmfoppjjkcencpbjaigfahdjlgpegn。然后在上面的目录中找到对应的目录,将该目录备份,然后在另外的系统中对应的位置恢复该目录即可。

Re-Packaging

在扩展页面,左上角有一个 Pack,选择扩展的根目录,然后选择 Pack 就可以得到一个 crx 文件。

reference


2020-07-24 chrome , google-chrome , chrome-webstore , chrome-extension , javascript

Docker 网络与容器互联

简单整理一下 Docker 中 network 子命令,以及 docker 中相关 network 方面的内容。

在安装完 Docker 后,使用 ifconfig -a 查看可以看到多出一个虚拟的 docker0 接口,这个接口是 Docker 默认的网关地址。

不同 Network driver 介绍

Docker 容器默认有三种连接方式:

  • bridge,网桥模式
  • host,宿主机模式,容器直接使用宿主机的网络
  • none

bridge 模式

Docker 默认会生成一个 docker0 网桥,如果不指定,默认创建的容器都会默认走此网桥,使用 bridge 模式联网。默认 bridge 会产生 docker0 的虚拟接口,在宿主机上可以使用 ifconfig -a 来查看,一般的网关地址是 172.17.0.1,所有的容器都会使用这个地址作为网关,容器的 IP 地址会从 172.17.0.2172.17.0.254 这个范围 IP 段划分。

  • 此模式下,容器可以单向连接外网,外网或宿主要访问容器则需要容器映射端口。
  • 连接同一个 docker0 网桥的容器之间可以彼此通过 IP 直接通信,无需 NAT ,但不建议直接使用各个容易的 IP,建议使用容器的 Link 机制 ( docker run 的 link 和 name 属性) 来让容器互联 ( link 的容器会作为主机名记录添加到容器的 /etc/hosts 中)。

host 模式

host 模式等同于容器直接使用物理机的网络,宿主机的 IP 就是容器的 IP,端口也可以直接调用。

  • 此模式的缺点是容易造成宿主机和容器端口冲突,而且降低了安全性,在有多个容器的情况下使用也不方便。
  • Mac OS 下,host 是一个运行精简版 Linux (boot2docker) 的 virtualbox,在 Ubuntu 上,host 就是物理机

none

none 模式,也就是容器默认不联网的模式。通常会合自定义网络的容器一起使用。non 在 swarm 服务中不可用。

macvlan

还有两种更高级的网络模式,overlay 和 macvlan,分别用于跨宿主机的容器通信和给每个容器分配一个 mac 地址。

macvlan 网络允许给容器分配一个 MAC 地址,这样在网络中就可以以物理设备存在。Docker daemon 会通过 Mac 地址将流量导给容器。在处理一些历史遗留应用,期望直接使用物理网络的场景非常适合使用 macvlan.

overlay

Overlay 网络会连接多个 Docker daemon,开启 swarm 服务来相互通信。也可以通过 overlay 网络来帮助 swarm 服务和独立容器之间的通信,或者帮助两个独立的容器,或者帮助不同的 Docker daemons。通过 overlay 就不需要系统级别在不同容器中的路由了。

Docker 本身也有一个 link 指令,可以用于连接两个容器,但这命令的缺点是只能单向连接,也就是 A 和 B 两个容器,只能 A 访问 B 或者 B 访问 A,做不到 AB 之间直接同时互访。

使用

创建新网络

docker network create network-name

docker network create -d bridge network-name

使用 ls 查看:

docker network ls

审查 network 信息:

docker network inspect network-id

删除网络:

docker network rm name
docker network rm network-id

创建时指定 IP 段:

docker network create --subnet=192.168.1.0/24 net-name

创建名为 net-name 的网络,默认 bridge,IP 段是: 192.168.1.0 ~ 192.168.1.255

reference


2020-07-20 docker , network , ip

MacBook Pro 初始设置记录

这里就简单的记录一下我从 Linux Mint 迁移到 MacOS 根据我的个人需求来初始化新的 MacBook Pro 的一些设置,和一些基本的感想。下面的内容会按照我自身的需求出发,我会列举我想要的功能然后在此基础上我需要借助哪些工具来实现。在切换到 MacBook Pro 之前,我使用了大约 6 年多的 Linux Mint,我已经有一套我自己的 Workflow,在切换到 Mac OS 之前我就在想哪一些的事情我是必须有 Mac 的软硬件才能做到,并且很提高某一方面的效率的,我列了一些

  • 被很多人追捧的触摸板,当然这个是硬件软件的结合其他系统可以追赶但体验确实不如 Mac 完整
  • 一些无法在 Linux 上跑起来的应用,一些基本工具应用,Adobe 系列的软件主要是 Lightroom

选购考虑

i7 2.6 vs i9 2.3

Macbook Pro have two different CPU specification, which is 2.6 GHz 6-core i7 and 2.3 GHz 8-core i9 processor.

The i9 9980H (2.3ghz) is 4% faster per core, and ~25% faster under full load than the i7 9750H (2.6ghz). $100 is ~4% of the price difference at that spec.1

The i9 9980HK (2.4ghz) is 5% faster in every situation than the i9 9980H.

Whether that will make a difference for you at all is highly dependent on what you are doing with it. If you are not compiling software, rendering, doing video compositing/encoding, or other parallelized high CPU tasks, it probably won’t.

16G vs 32G

内存是必需品,如果需要大量使用 Chrome,或者依赖于 IDE,或者需要同时开多个应用,大一些的内存还是必要的。

基础设置

首先是一些必要设置的设置,后面的一切都依赖这些设置。

设置代理

国内的网络环境,这已经成了所有设置的基础,甚至我想先下载一个 Chrome 都需要依赖代理设置好。首先从 GitHub 下载 ClashX,然后导入 v2ray 配置。(或者可以用 v2rayU, Qv2ray)

ClashX 的配置文件在 ~/.config/clash/ 目录下。

在终端中要进行代理:

# 设置 socks5 代理
export http_proxy="socks5://127.0.0.1:1080"

alias

 alias setproxy="export ALL_PROXY=socks5://127.0.0.1:1080" alias unsetproxy="unset ALL_PROXY"

或者设置 curl (curl >= 7.21.7) 代理:

curl -x socks5h://localhost:1080 http://www.google.com/

安装浏览器

在其他系统上在浏览器中的时间伴随着我使用系统的时间,大量的事是在浏览器的页面中完成的,比如在 Trello 中记录时间,比如收发邮件,比如密码管理等等。

有了代理,就可以很快的安装上 Google Chrome,然后登陆账号,没几分钟我所有的同步设置就全部来了,包括书签,插件,甚至历史记录。

LastPass 插件登录,密码同步;Trello 登录,代办事项同步;Tampermonkey 需要到设置中开启高阶设置,然后启用浏览器同步,所有的 userscripts 也同步过来了。等等还有很多的插件也一并同步了。Chrome 此时就已经可以是日常使用了。

输入法

我使用小鹤双拼,在开机设置的时候我就已经选择了双拼,然后在输入法中简单的设置一下使用小鹤双拼即可。在 Mac 下使用 Ctrl+Space 来切换输入法。

系统自带的小鹤双拼用起来似乎还没遇到什么大问题,先不配置 Mac 下的 Rime 了。如果需要编译安装 Squirrel 可以按照这个文档安装。

double-pinyin-flypy.png

开启 SSH 远程登录

在系统设置 Sharing 中需要开启远程登录,这样就可以通过 ssh yourname@<mac.ip> 来登录系统了,非常方便我在局域网中将我原来的配置以及文件通过 rsync 传输过来。

Mac 上的包管理 homebrew

Linux Mint 上继承了 Debian/Ubuntu 系列的 apt 包管理工具,一些工具的安装非常方便,Mac 下有 homebrew。

官网 下载安装即可,如果遇到说 curl 443 端口连接不上,那就只能先 Chrome 上把这个脚本下载下来,然后 bash install.sh 来手动安装了。

homebrew 也还提供了字体安装的支持,安装 homebrew-cask-fonts

brew tap homebrew/cask-fonts                  # tap 类似于 apt 中添加第三方源的 add repository
brew cask install font-inconsolata
brew cask install font-fira-code
brew cask install font-source-code-pro

brew tap homebrew/cask-drivers

然后配置国内镜像,加速下载。

brew 常用的命令:

brew search package_name
brew info package_name
brew install package_name
brew update
brew upgrade package_name
brew uninstall package_name
brew list
brew config
brew doctor
brew uninstall package_name

所有的 brew cask 包,可以到这里 查看。

homebrew 会将软件安装到 /usr/local/Cellar,然后通过软链接链接到 /usr/loca/bin 目录。

brew install asdf tree tmux hub p7zip openssl curl node automake autoconf ack
brew install macvim --with-cscope --with-override-system-vim --with-lua --HEAD
brew install coreutils curl git asdf
rehash

brew 和 brew cask 的区别在于 cask 用来安装 GUI 软件。

brew cask

brew cask install anki alfred eudic iterm2 visual-studio-code

brew 的备份和恢复,如果要在两台 Mac 间备份和恢复 brew 安装的包,可以使用:

brew bundle dump    # dump
brew bundle         # 恢复

brew bundle dump 会生成一个 Brewfile 文件,这是一个纯文本的文件,里面列举了系统上的 brew 配置和安装的列表,那么我只需要维护一个 Brewfile 文件就可以一键安装必备的命令和桌面软件了。

通过 App Store 安装的应用可以通过 mas 来管理。

手势

一直都说 Mac 的手势领先其他厂商,个人初使用来看确实非常顺手,没有卡顿,并且大面积的触摸板使用体验确实不错。

除了常用的双指上下滚动,左右翻页还有这样一些操作:

  • 三指向上,Mission Control,会显示当前所有打开的窗口
  • 三指向下,可以显示同一个应用的不同窗口
  • 三指左右,可以在全屏的应用间切换
  • 四指捏合,显示 Launchpad
  • 四指放开,显示桌面

但是关于选择页面中的文本在 Mac 就比较有趣了,我一般的行为模式就是用左手大拇指双击进入选择模式,然后接触触摸板选择文字释放左手大拇指。我这个操作习惯在 Mac 需要用力按下触摸板选择,后来在 System Perferences -> Accessibility -> Mouse & Trackpad -> Trackpad Options -> Enable dragging without Drag Lock 找到了设置。

这个选项里面有三个选择:

  • without drag lock
  • with drag lock
  • three finger drag

很多人推荐开启第三个,我个人不太喜欢,明明能有用一个指头完成的事情为何要用三个指头。

但前两个就有点暧昧不清了,这里具体解释一下:2

  • without drag lock: 这个模式下的拖拽选择操作是这样的:1. Double tap 然后第二次 Tap 不放开,直接开始拖拽,然后放开;2. 然后根据最后停顿的时间来判断是否结束选择,如果是短暂的停顿则即使松开手指也会继续在选择模式,直到再 Tap 一下触摸板,而如果在选择时有较长的停顿,操作系统则认为选择结束
  • with drag lock: 则是 Double Tap 然后不放开手指进入选择模式,松开手指也会继续在选择模式中,直到再 Tap 一下停止选择。

我个人的习惯还是选择了第一个 without drag lock.

编程开发工具

iTerm

官网 下载安装即可。

zsh, vim, tmux 的配置放在 dotfiles 项目管理。

git clone git@github.com:einverne/dotfiles.git
ln -s ~/dotfiles/.zshrc ~/.zshrc
source ~/.zshrc

ln -s ~/dotfiles/.vimrc ~/.vimrc
# 然后进入 Vim,执行 `:PlugInstall`
ln -s ~/dotfiles/tmux/.tmux.conf ~/.tmux.conf
ln -s ~/dotfiles/tmux/.tmux.conf.local ~/.tmux.conf.local

配置和 Guake 类似的下拉显示。

  • 在 iterm2 的设置菜单中 Keys -> Create a Dedicated HotKey Window…
  • 创建新的 Profile,在菜单中设置呼出快捷键,但是在 Mac 上因为 Touchbar 的诡异存在,使得我无法方便的按下 F12,所以只能选用其他的按键

JetBrains Toolbox

下载 JetBrains Toolbox,然后一个个选择想用的 IDE。

SmartGit

官网 下载,我个人非常喜欢的一个 Git 客户端,跨平台,页面也很清晰。不过简单的提交和使用 IntelliJ IDEA 自带的 Git 管理也已经足够好了。

设置 GitHub SSH Key

设置 GitHub 的 SSH Key。

ssh-keygen -t rsa -b 4096 -C "your_email@example.com"

然后 clone 我的 dotfiles 配置,笔记,wiki 等等配置。

默认软件的熟悉

Finder 中显示 Home 目录

使用快捷键 Command+Shift+H

鼠标滚轮的方向

虽然大部分的情况下触摸板和快捷键已经能满足一定的需求,但有些时候还是会接上鼠标,尤其是当连接显示器将 Mac 作为主机使用的时候,这个时候我就发现一个问题,那就是鼠标滚轮的方向和我在 Linux 下养成的习惯相反了,看网上的材料说设置里面可以设置更改鼠标 nature 的方向,但是修改过后发现触摸板的双指滚动方向也跟着变了,然后继续搜索发现很多人推荐 Scroll Reverse 但是这个小工具在 OSX10.15 及以上有兼容性问题,继续搜索就发现了 Mos,这个软件可以更改鼠标滚动的方向,也可以让滚动更加平滑。

常用快捷键

Mac 的快捷键设计有一个非常容易的记忆方法,和 UI 相关的快捷键基本上和 Cmd 相关,和 Ctrl 相关的大多数是终端内的操作。所以 Cmd 组合 Q/A/Z/C/V/X/T/H/M 等等都是和界面窗口标签页相关的,而 Ctrl 和 a/e/n/p/b/f 都和终端中光标移动或者终端中字符处理相关的。

在打开的窗口中显示隐藏的文件:Cmd+Shift+.

默认在 Finder 中显示所有文件,包括隐藏文件。

defaults write com.apple.finder AppleShowAllFiles TRUE
killall Finder

Cmd 快捷键

快捷键 说明
Cmd + Q 退出应用
Cmd + W 关闭当前窗口,关闭 Tab
Cmd + X/C/V 和其他系统类似,剪切,复制,粘贴
Cmd + Tab 切换打开的应用
Cmd + ` 切换同一个应用的多个窗口,当然结合触摸板的四指下滑也可以
Cmd + , 打开大部分应用的偏好设置
Cmd + [ 后退
Cmd + ] 前进
Cmd + Space Spotlight search
Cmd + L 定位到地址栏,非全局快捷键,在 Chrome 中非常好用
Cmd + A 全选
Cmd + Z 撤销上一次操作,Cmd + Shift + Z 重做
Cmd + F 页内搜索
Cmd + G 搜索下一个, Cmd +Shift+G 上一个
Cmd + H 隐藏最前面的窗口,这个操作不可逆,我应该不会用到
Cmd + M 最小化前面的窗口到 Dock,也不可逆,所以我也不用
Cmd + N 新建窗口
Cmd + O 打开文件
Cmd + P 打印当前文档
Cmd + S 保存

截屏的快捷键

快捷键 解释
command + 1 左边的按键 在同一个应用不同窗口间切换
Shift+command+3 截取全屏
Shift+command+4 截取部分,通过光标选择
Shift+command+5 打开截取工具,有更多选项

在大部分的文档类应用中了解这些快捷键也可以提升不少效率

快捷键 说明
Cmd + B 加粗
Cmd + I 斜体
Cmd + K 插入链接

Ctrl 快捷键

上面提到的 Mac 下的 Ctrl 快捷键大部分是和终端或者输入框中的文字相关的,Ctrl 的组合在 Linux 的终端,Emacs 中也有不少的应用。

快捷键 说明
Ctrl + a/e 光标跳转到行首,行尾
Ctrl + b/f 光标向前 (backward), 向后 (forward) 移动一个字符
Ctrl + n/p 下一个 / 上一个
Ctrl + h/d 向前删除一个字符,向后删除一个字符
Ctrl + k 删除光标都末尾所有内容,这个快捷键在我的配置中设置了切换到上一个 Panel,所以我不怎么用
Ctrl + w 删除前面一个单词 (WORD)
Ctrl + u 删除直到行首

Mac 全部快捷键

Mac 有个 Wired 的快捷键组合,在 Linux 终端下,向前向后跳转一个 Word 是 Alt+b/f, 但是 Mac 下默认是 Esc+b/f,这个默认的快捷键太奇怪了,想象一下在键盘上按住 Esc 在按 b/f 的姿态,一个手几乎是做不到的。所以把 Esc 按键 remap 到 Caps Lock 也算是一种勉强的解决方法吧。不过更好的方法,以及延续我的习惯,我在 iTerm2 中可以设置一下 Option+b/f。

  • Open iTerm.
  • Go to iTerm > Preferences… > Profiles > Keys
  • Under Profile Shortcut Keys, click the + sign.
  • Type your key shortcut (option-b, option-f, option-d, option-left, etc.)
  • For Action, choose Send Escape Sequence.
  • Write b, d or f in the input field.

From: https://apple.stackexchange.com/a/154296/149497

其他需求

查字典

查字典是我个人非常频繁的一个需求,虽然 Mac 自带的词典日常使用已经完全够用,并且集成到系统的 Lookup 功能也是非常好用,但我个人还是比较喜欢 Ctrl+C+C 这样的快捷键。我个人的需求不仅是英文的字典,有的时候还会查阅韩语或其他语言的字典,我个人偏好离线的字典,所以一直一来使用的是跨平台的 GoldenDict,从 GoldenDict GitHub 页面下载安装即可。我个人的需求:

  • 离线查词,包括我自己常用的英语和韩语
  • 导入我常用的词典,牛津,朗文,以及相关的同义词,词源字典
  • 支持句子翻译,GoldenDict 可以支持自己定义脚本,所以我修改了一下 skywind3000 的脚本,添加了 Google,Yandex, Youdao 的长句子翻译,我只要选择句子或段落,Ctrl+C+C 即可直接在任何地方翻译该文本

压缩图片的需求

在 Mac 上随便截一张图可能就是 7,8MB 大小,非常不适合在互联网上分享,我一般会使用 Google 的 Squoosh 来进行压缩。

有些人推荐 squash 这款软件,简单的看了一下官网,似乎就我这个需求并不需要 Squash 这款软件。

多重粘贴板

在 Linux 上我使用 fcitx 自带的粘贴板 Ctrl+; 就可以呼出,因为就是输入法的功能,所以非常方便。在 Windows 下用 Ditto 这样一款软件。那么切换到 MacOS 就想要一个代替品。

brew cask install maccy

默认是 Shift+Cmd+C 弹出粘贴历史,我习惯了 Ctrl+; 所以直接改成这个快捷键。

在文件管理器 Finder 中快速打开终端

借助 OpenInTerminal 这个 Finder 的插件可以实现在 Finder 目录中,立即打开终端。

借助这个插件还可以:

  • 选中的文件夹,通过 Vim,或者其他编辑器直接打开
  • 快速复制当前的路径

这里不得不吐槽一下,文件管理器,Mint 中的 nemo 使用起来要舒服多,这上面的操作,右键就能完成,完全不需要额外安装插件。

改键的需求

在 Mint 我已经有了一套熟悉的快捷键,现在到了 MacOS 上一边熟悉自带的快捷键,也想对默认的一些快捷键做修改,这个时候就需要 Karabiner-Elements。

Karabiner-Elements 比较强大,可以自定义修改几乎键盘上的每一个键,不过我个人并不推荐把键盘修改的面目全非,这需要花费很长的时间来适应。

Karabiner-Elements

在使用 Karabiner 的时候发现组合键 Cmd+F12 等等 Fn 键,表现的就像是没有按下 Cmd 按键一样,最后发现需要在 Karabiner 中设置 Devices 才可以生效。

另外我将 Caps Lock 作为一个 Hyper Key,按下 Caps Lock 相当于同时按下 Cmd+Ctrl+Shift+Option, 这样 Caps Lock 就可以结合其他按键作为一个新的组合按键,在利用 Hammerspoon 可以实现一套自己的快捷键工作习惯,比如我个人将 Hyper Key + HJKL 作为调整窗口的快捷键,Hyper Key+NP 作为调整窗口在哪一个显示器的快捷键。

Karabiner 之后也会用一个篇幅来介绍一下。

Telegram 即时聊天工具

去 Telegram 官网看,发现 MacOS 下有两个客户端,一个叫做 Telegram Desktop,这个和 Windows 和 Linux 放在一起;另一个叫做 Telegram for MacOS,简单了解一下后,发现这个客户端是单独用 Mac 的原生语言实现。这两个的区别在于 Telegram Desktop 使用跨平台的实现,所以体验上和其他两个平台相似,原生实现的 Telegram for MacOS 则提供了加密等额外的功能。

文件同步需求

从 Dropbox 换成了 分布式的 Syncthing.

Syncthing 的配置设置$HOME/Library/Application Support/Syncthing.

另外也会用中心化的 NextCloud 作为备份。

播放器需求

开源的选择 IINA

或者老牌的 VLC

笔记的需求

历史的笔记在为知笔记里面,下载,登录数据就回来了。

WizNote 打开的时候显示不被认证的开发者,需要执行

sudo spctl --master-disable

开启信任任何来源的安装,当然这个操作会降低系统的安全性,谨慎!

另外今年起,我渐渐的将笔记迁移到了 Obsidian.

我在 GitHub 上新建了一个 Private 的项目来同步 Obsidian 的笔记。

听音乐的需求

唯一的选择,网易云音乐,我之前也写过文章,在体验过市面上所有的音乐软件后,选择了网易,然后已经很多很多年了。

Dash 文档查看

官网 下载安装。

窗口管理

在 Mac 上我发现我无法想在 Mint 中拖拽窗口到左右边缘,然后将窗口左右分屏,导致现在 Mac 上的窗口层层叠叠,管理起来非常的不方便。找了几个开源的工具。

体验了一下之后选择了 Rectangle,虽然也看到了 MacOS 上的平铺窗口管理。

但这些都需要大量的定制,所以先放着了。

图片预览及管理

Pixea 一款优秀的看图软件。

录制 GIF

LICEcap

压缩解压缩

状态栏显示 CPU 内存网速

虽然 iStat Menus 很强大,但看看 CPU 和内存占用,网速,用开源的 iGlance 足矣。

电子书管理

Linux 和 NAS 上一直用的 Calibre

brew cask install calibre

HTTP 接口调试

因为历史上保存了一些请求,所以还是用了 Postman,不过新出的 Postwomen 也可以试试。

抓包工具

大名鼎鼎的 Charles,以及命令行 mitmproxy, 以及网络协议的 Wireshark 都来一套。

FTP 文件传输分享

  • Cyberducker
  • Transmit

下载工具

aria2, you-get 和 youtube-dl 日常使用,Transmision 作为 BitTorrent 备用。

密码管理

自己搭建的 Bitwarden,虽然常年使用 LastPass,但最近自己搭建 Bitwarden 后发现 Bitwarden 跨平台做的非常不错,还可以利用起 Mac 的 Touch ID。

状态栏隐藏

开了很多应用,导致状态栏非常乱,很多人推荐收费的 Bartender 3,不过试了一下发现开源的 Dozer 也非常不错。

Finder 增强

在 Finder 中点击直接打开终端到当前文件夹。

brew cask install go2shell

在屏幕上显示输入

在 Linux 下我使用一个叫 screenkey 的工具,在 Mac 上也找到一个类似的开源项目 keycastr.

brew cask install keycastr

记录和管理外接显示器

如果经常使用 Mac 外接显示器使用,就会发现如果断开连接之后再连接,系统对外接显示器的记忆就丢失了,这个时候还需要到设置中进行一番设置。

自动化工具

最开始只是想做到在不同的 WiFi 环境下使用不同的 DNS 配置,所以发现了 Hammerspoon 这个开源的自动化工具,不过发现 Hammerspoon 太强大了,可以代替上面提到的很多个工具,以后会再加一篇文章单独介绍一下 Hammerspoon。

Tiling Windows Manager

yabai

使用 Touch Id 授权 sudo

如果经常修改系统配置,常用 sudo 命令就需要输入一串密码,在 Mac 下可以使用 Touch Id 来验证密码。

sudo sed -i ".bak" '2s/^/auth       sufficient     pam_tid.so\'$'\n/g' /etc/pam.d/sudo

这一行命令的作用是把 /etc/pam.d/sudo 备份为 /etc/pam.d/sudo.bak,然后在 /etc/pam.d/sudo 的第二行前面加入 auth sufficient pam_tid.so

要恢复就使用:

sudo mv /etc/pam.d/sudo.bak /etc/pam.d/sudo

Touch Id 的妙用还可以参考:pam-touchIDpam_touchid.

查看监听的端口

Mac 上使用 netstat 显示监听的端口:

netstat -an | grep LISTEN

或者使用 lsof:

sudo lsof -iTCP -sTCP:LISTEN -n -P

lsof 可以看到具体某个端口关联的 PID。

开发环境安装

上面提到基础的编程环境安装,这里在针对具体细节补充说明。

安装 asdf 多版本管理

asdf 是一个命令行下的多语言,多版本管理工具,我之前的文章提到过 pyenv 安装管理多个版本的 Python, 同样的我在外延部分提到了 Java 的多版本管理 jenv, 还有 Ruby 的多版本管理 rbenv,甚至还有 node.js 等等语言,等等编译工具的多版本管理工具,而 asdf 将这些多版本管理工具都整合到一起,通过简单的 asdf 一行命令就可以搞定很多二进制工具,或语言的版本管理,asdf 通过扩展的方式支持了非常多的常用工具。在 Mac 下的安装也非常简单,直接参考官方网站 即可。

安装 Java 开发环境

asdf plugin add java
asdf install java adoptopenjdk-8.0.262+10.openj9-0.21.0
asdf install java adoptopenjdk-11.0.8+10.openj9-0.21.0
asdf global java adoptopenjdk-8.0.262+10.openj9-0.21.0
java -version

安装 maven

asdf plugin add maven
asfd install maven 3.6.2
asdf global maven 3.6.2
mvn --version

安装 Python 环境

asdf plugin add python
asdf install python 3.6.1
asdf global python 3.6.1
python -V

Nodejs

asdf plugin add nodejs
bash ~/.asdf/plugins/nodejs/bin/import-release-team-keyring
asdf install nodejs 14.5.0
asdf global nodejs 14.5.0
node -v
yarn -v

安装 MySQL 管理工具

我使用 MySQL 官方的管理工具 MySQL Workbench.

迁移 Lightroom 图片库

我的很大一部分照片库在 Windows 的 Lightroom 中,幸亏 Lightroom 的迁移并不麻烦,在 Windows 上使用 WinSCP,然后局域网连上 Mac,直接将 Lightroom 所在的 Pictures 图片库复制到 Mac 上面的图片库中,然后将 Lightroom 的 .lrcat catalog 文件夹也拷贝到 Mac 上,这个目录可以在 Windows 的“编辑”-“目录设置”中找到。

拷贝完成后在 Mac 上打开 lrcat 文件,然后在 Lightroom 中右击文件夹,Find missing folder,重新导入就 OK 了。

配件选购

拓展坞

选择拓展坞的时候看了京东上面的大部分牌子,也参考了一些帖子,无疑如果不差钱直接上贝尔金,CalDigit TS3 Plus,雷电 3 的拓展坞一步到位即可。但我自己并不需要 4K60Hz,也用不上那么大的带宽,我目前的需求只需要一个可以用的 HDMI 扩展,一个 USB 外接鼠标,最好再带一个 SD 卡槽,剩下的 VGA,RJ45 网口我并不是必须,所以开始的时候直接买了贝尔金的 Tpye-C 的拓展坞,京东下单叠加了一个优惠大概 500,但是拿回来之后试用了两天就发现了问题,我只接一个 USB 的时发热也有些大,另外一个致命的问题就是 SD 卡的读取速度真的和测评里面看到的一样 20M 就上不去了。所以果断退货换了一个飞利浦的 7 合 1(HDMI,SD/microSD,Tpye-C,三个 USB),回来立即试了一下 SD 读取,以及发热问题,在只用 USB 接口的时候几乎感受不到温度,SD 卡也可以轻松地到 70M,就他吧。(另外要提一下为什么不买绿联的拓展坞,在京东上销量几乎被绿联拿走了一大半,但是我已经不止一次的看到过因为绿联的拓展坞从而导致接口损毁,甚至影响主板,导致重启的问题,所以直接排除在选择范围了)

疑难杂症

解决 rsync 乱码问题

Mac 自带的 rsync 会遇到乱码问题,使用 brew 重新安装

brew install rsync

.app cannot be opened because the developer cannot be verified

在安装应用时,有些应用没有上架到 App Store,比如 GoldenDict,Mac 在安装的时候就会提示上面的错误,并且没有办法打开,这个时候就需要到设置中 Security&Pravicy 中,将 Allow apps downloaded from 选项中的 All 打开。

Mac 上 Chrome 遇到 NET::ERR_CERT_INVALID

我使用的 Resilio Sync 的后台管理界面使用了 BitTorrent 自己签发的证书,所以 Chrome 中打开的时候会报错“NET::ERR_CERT_INVALID”,普通情况下我知道该风险,在其他操作系统中会提供一个选项,点击高级可以继续访问链接,但是在 Mac 上并没有这个按钮,我搜索了一下,想要尝试信任证书,无果,后来发现一个神奇的方法,在页面中点击空白处,然后输入:thisisunsafe,即可。略神奇。

几点吐槽

  • 念念不忘的 Touchbar,真的很鸡肋
  • 右上角的日期竟然连日历都没有,幸好有 day-o 和 Itsycal 这样的扩展,勉强可以用
  • 分屏功能竟然需要第三方扩展来支持,虽然可以用 Option 来左右分屏,还是很鸡肋,连 Linux Mint 自带的桌面都赶不上
  • 自带的 Finder,是我没有使用习惯吗?我觉得 Nemo 还是要远远好过 Finder

reference


2020-07-19 unix , macos , setup , github

电子书

最近文章

  • 使用 zinit 管理 zsh 插件 一直使用的 antigen 来管理 zsh 的插件,但是最近 zsh 加载因为加了一些插件变的非常慢,所以就像找找办法提速 zsh,在查询的过程中发现 antigen 已经很久没有更新,很多人推荐 antibody, 于是又试了一下 antibody, 不过在调研的过程中又发现了 zinit. 之后经过对比,发现 antibody 所谓的并行执行也没有提速很多,反而是名不见经传的 zinit 通过配置将加载时间稳稳的降低,在新建终端时几乎立即可见。
  • 阿里云函数计算中使用 Python psycopg2 访问 PostgreSQL 在之前的文章中提到过 函数计算 但一直没有正式的用起来,现在正好通过在阿里云函数计算中连接访问 PostgreSQL 来系统性的学习一下阿里云的函数计算。 首先要了解的几个概念:
  • Mac OS 上的平铺窗口管理工具 yabai yabai 是一个 Mac OS 上的平铺窗口管理工具。Linux 上很早就有一系列的平铺窗口管理工具,比如 i3, awesome 等等。yabai 将这个功能带到了 Mac 上。所谓的平铺式窗口管理,是相较于普通的浮动窗口管理,在通常使用的情况下,系统上的应用如果打开了很多,就不可避免的相互叠加,需要频繁的使用 ⌘+Tab 来切换窗口。而平铺式窗口管理,则将所有的窗口平铺在桌面上,窗口之间不会相互重叠。
  • You Quiz on the Block E70 世代差异 Covid-19 以来很少有让我继续追下去的韩综,除了带我入坑的周末综艺,一个 《[[Begin Again Korea]]》剩下的就只有《You Quiz On the Block》了。可以看得出来韩国的综艺人,电视人总还是带着一些社会关怀再做内容,之前在《Begin Again》里面就提过,在这个特殊的时代,他们把歌声第一时间先给一线的医护人员,公共服务人员,在这个疫情的特殊时期《Begin Again》就是一个治愈的存在,而相同的《You Quiz》第三期开篇就是对社会一线人员的致敬,公交司机,私营店老板,快递员,防疫人员,社会正是在这些人继续工作下去的时候才能维持正常的运行。
  • 使用 Goku 配置 Karabiner Karabiner 是 MacOS 上一款强大的自定义键盘的软件,可以非常自由的定义任何键位。