xxleyi / learning_list

聚集自己的学习笔记
11 stars 3 forks source link

Programming My Daily Work #31

Open xxleyi opened 5 years ago

xxleyi commented 5 years ago

little code or idea which can automate my daily work.

xxleyi commented 5 years ago

Python Debug: Log to My clipboard

xxleyi commented 5 years ago

vscode snippets function

比较了一下,发现 vscode 的 snipptes 功能比 Alfred 的更强大一下,可以针对不同语言进行设置,而且可以用同步设置的插件进行同步。很棒,接下来要把这个功能用起来,正好要进行重构代码工作,一个可以把 snipptes 培养成习惯的好时机。

xxleyi commented 5 years ago

输入法自动切换

⚠️ 已经找到更好的方法,在 hammerspoon 生态中

#! /usr/bin/env python
# coding: utf-8

# ! 自动切换输入法的最终解决方案:
# ! 利用 issw 和 MacOS 自带的切换前台应用时发出的通知

'''
auto switch input method between different applications

if you want to change the app list, modify the var 'en_list' and 'zh_list',
or add your own custom_list.
'''

from __future__ import unicode_literals
from __future__ import division
from __future__ import print_function

from subprocess import call, check_output

from AppKit import NSWorkspace, NSWorkspaceDidActivateApplicationNotification, NSWorkspaceApplicationKey
from Foundation import NSObject
from PyObjCTools import AppHelper

# !add your custom apps here, check the bundle id in /Application/xx.app/Contents/info.plist
# !or use command: osascript -e 'id of app "Safari"'

en_list = [
    "com.googlecode.iterm2",
    "com.google.Chrome",
    "com.apple.Terminal",
    "com.sublimetext.3",
    "com.apple.Safari",
    "com.sequelpro.SequelPro",
    "com.microsoft.VSCode",
]

zh_list = [
    "com.tencent.xinWeChat",
    "com.tencent.WeWorkMac",
    "com.workflowy.desktop",
    "com.apple.Notes",
    "com.soulmen.ulysses3",
]

def get_avaliable_input_methods():

    return check_output(["issw", '-l']).decode().strip().split('\n')

class Observer(NSObject):
    def handle_(self, noti):
        info = noti.userInfo().objectForKey_(NSWorkspaceApplicationKey)
        bundleIdentifier = info.bundleIdentifier()
        if bundleIdentifier in en_list:
            print("found: [%s] active, switch to US" % bundleIdentifier)
            call(["issw", "com.apple.keylayout.ABC"])
        elif bundleIdentifier in zh_list:
            print("found: [%s] active, switch to Shuangpin" % bundleIdentifier)
            call(["issw", "com.apple.inputmethod.SCIM.Shuangpin"])

def main():
    nc = NSWorkspace.sharedWorkspace().notificationCenter()
    observer = Observer.new()
    nc.addObserver_selector_name_object_(
        observer,
        "handle:",
        NSWorkspaceDidActivateApplicationNotification,
        None
    )
    AppHelper.runConsoleEventLoop(installInterrupt=True)

if __name__ == '__main__':
    main()
xxleyi commented 5 years ago

Loose JSON string Parse

function run(argv) {

  String.prototype.replaceAll = function(search, replacement) {
    var target = this;
    return target.replace(new RegExp(search, 'g'), replacement);
  };

  function looseJsonParse(obj){
    return Function('"use strict";return (' + obj + ')')();
  }

  var query = argv[0];
  var format_str = (source={}) => {
    let str = (obj) => JSON.stringify(obj, null, 4); 
    return str(source); 
}

  query = query.replaceAll('\n', '')
  return format_str(looseJsonParse(query))
}
xxleyi commented 5 years ago

How to Paste Everything as Plain Text

Try to copy something from a web page into your email, and you’ll find that the result is distorted by HTML and other unnecessary bits. Here’s how you can prevent that using a simple workaround that does not rely on the use of a third-party app.

  1. Open System Preferences from the Apple menu and select Keyboard.
  2. On the Keyboard panel, select the tab for Shortcuts.
  3. Scroll down the list on the left and select App Shortcuts.
  4. Click the “+” below the boxes to add a shortcut.
  5. Select All Applications for Application input box. This (theoretically) will apply the shortcut across the board.
  6. Type Paste and Match Style(系统语言为中文时名称为「粘贴并匹配样式」) into the Menu Title input box. This takes the copied text and pastes it in using the current document’s formatting.
  7. set shift+command+v
xxleyi commented 5 years ago

少用 rm,优先考虑 trash 命令

brew install trash

xxleyi commented 5 years ago

autoenv 自动执行shell脚本

自动激活 Python 虚拟环境

#source "${AUTOENV_CUR_DIR}/.venv/bin/activate\""
if [[ "${AUTOENV_CUR_DIR}" == "\"$PWD" ]] then
source .venv/bin/activate
fi
xxleyi commented 4 years ago

alfred top precess workflow

安装新系统之后,往往不能工作,此时应该是 ruby 的依赖被破坏。重新安装,可能需要 sudo 权限。

sudo gem install alfred-workflow
sudo gem install mixlib-shellout -v 2.2.6
xxleyi commented 4 years ago

autoexpect: shell auto workflow

autoexpect command => script.exp => 加工修改 => real.exp

#!/usr/bin/expect
#  参数1: jumpserver  参数2: server_ip

if { $argc != 2 } {
    send_user "Usage:  jumpserver, server_ip \n"
    exit
}

set force_conservative 0
if {$force_conservative} {
    set send_slow {1 .1}
    proc send {ignore arg} {
        sleep .1
        exp_send -s -- $arg
    }
}

set timeout -1

# 接收入参
set jumpserver [lindex $argv 0]
set server_ip [lindex $argv 1]

#开始执行自动 shell 交互
#登录跳板机
catch {spawn ssh $jumpserver}

#登录目标机
expect "*IP*"
send "/"
expect "*K/"
send "$server_ip"
send "\r"
expect "*36m"
send "\r"
expect "USERNAME"
send "username\r"
expect {
    "*yes/no*" {send "yes\r";exp_continue}
    "*assword*" {send "password\r";exp_continue}
    "*~*" {send "sudo su -\r"}
}
expect "*username*"
send "password\r"
expect "*~*"
send "screen -D -r supervisor\r"
# 将控制权交给用户
interact
xxleyi commented 3 years ago

相见恨晚的 Hammerspoon

Hammerspoon 可以完美实现的功能:

Alfred 生态中已经有全局搜索浏览器 tab 的插件,但毕竟是收费的,最近几天业余时间主要研究如何在 Hammerspoon 中完美实现,最终思路如下:

Hammerspoon 中已经有一个实现,但还不完美,存在某些问题,但是流程已经有了。

我做的改动是,提取 tabindex,windowindex,避免激活时再次查询一遍,同时各个浏览之间的激活方式也能使用更一致的方案。

提取 tablist 的脚本:

tell application "Google Chrome"
    set winlist to tabs of windows
    set tablist to {}
    set winidx to 0
    repeat with i in winlist
        set winidx to winidx + 1
        if (count of i) > 0 then
            set tabidx to 0
            repeat with currenttab in i
                set tabidx to tabidx + 1
                set tabinfo to {title of currenttab as Unicode text, URL of currenttab, tabidx, winidx}
                copy tabinfo to the end of tablist
            end repeat
        end if
    end repeat
    return tablist
end tell

safari 和 chrome 有一点不一样,不能用 title, 需要用 name

tell application "Safari"
    set winlist to tabs of windows
    set tablist to {}
    set winidx to 0
    repeat with i in winlist
        set winidx to winidx + 1
        if (count of i) > 0 then
            set tabidx to 0
            repeat with currenttab in i
                set tabidx to tabidx + 1
                set tabinfo to {name of currenttab as Unicode text, URL of currenttab, tabidx, winidx}
                copy tabinfo to the end of tablist
            end repeat
        end if
    end repeat
    return tablist
end tell

将特定 tab 带到前台的脚本(不得不说,方法很是诡异):

tell application "Safari" to set index of window 2 to 1
tell window 2 of application "Safari" to set current tab to tab 1

同时也可以考虑 JXA,而且搜索的时候可以同时搜索 AppleScript 和 JXA,有些大神喜欢用 JXA,有些喜欢使用 AppleScript。

但要知道Safari 对 JXA 的支持有限

另外还需要提到一点,很多时候,我们的 AppleScript 或 JXA 脚本需要从 lua 脚本中接受变量,这个时候该如何操作呢?

一开始我还以为 ]] .. someVar .. [[ 是某种特殊语法呢,坑了我一把。

建议使用 Mac 自带的脚本编辑器调试 AppleScript 和 JXA。

入门 JXA 的好文

学了一波之后,发现 JAX 也可以搞定 Safari,但是方法不一样:

#!/usr/bin/env osascript -l JavaScript

const safari = Application('Safari')
// need activate firstly
safari.activate()
safari.windows[winIdx].visible = true
// safari need take tab to frontmost by this way
safari.windows[winIdx].currentTab = safari.windows[winIdx].tabs[tabIdx]
safari.windows[winIdx].index = 1

反观 Chrome,是这样:

chrome.activate()
chrome.windows[winIdx].visible = true
chrome.windows[winIdx].activeTabIndex = tabIdx + 1
chrome.windows[winIdx].index = 1