These two days I’m studying how to effiently use Alfred 2. Yesterday I bought its Powerpack Single License (17 Euro), so that I can import or create my own Workflow!
I should say it is really fun to do such things, it makes me believing that I can take more control over my own Mac Air.
In this post I will show how to write a simple workflow using ruby. The code can be downloaded from my github page, it is a very simple program that can translate between each character and its corresponding ASCII code, just like this:
You can translate from an array of decimal ASCII code to their characters:
Or from hexadecimal ASCII code to their characters:
Or from characters to their corresponding ASCII codes:
So now let’s begin!
Firstly I should say why I use ruby is just because I like it! Thanks for zhaocai who have implemented the alfred2-ruby-template, which makes creating Alfred2 Workflow using ruby much more simpler.
At first, you should download the template from github, and rename it whatever you like:
$ git clone https://github.com/zhaocai/alfred2-ruby-template.git$ mv alfred2-ruby-template alfred2-ascii-translator$ cd alfred2-ascii-translator
update the domain
, id
, path
attribute in config.yml
file:
# bundle_id = "domain.id"# path is the relative path to the workflow in the project root---path: asciidomain: me.ytliuid: alfred2-ascii-translator# If you are using Alfred's advanced Dropbox sync, indicate the path shown in# Alfred Preferences > Advanced > Syncing:dropbox: ~/Dropbox/Alfred
the last option: dropbox
is when you use Alfred’s advance Dropbox sync, as explained above, you can find in Alfred Preferences > Advanced > Syncing
After that, we can change the main folder to what we want it to be (actually here you can remain as before: workflow
, but make sure the path
attribute in config.yml
should be consistent with it).
$ mv workflow ascii
Now we should setup our ruby environment.
Firstly, we can create a new gemset (I’ve been stuck in the gemset problem for a long time, where there’re many versions of gem packages and make me confused. So here just create a new one, and make it clean).
$ rvm gemset create alfred_ruby_set$ rvm use 2.0.0@alfred_ruby_set
Note here the ruby version I’m using is 2.0.0, I think other version can also be ok.
At the very beginning of installing all other gems, we should install the plist
and bundler
gem:
$ gem install plist$ gem install bundler
Then install other gems using bundle:install
:
$ rake bundle:install
Normally it will install all the gems you need. The gems are list in the Gemfile
file (e.g., here it is the ascii/Gemfile
).
$ cat ascii/Gemfile
source "https://rubygems.org"gem "plist"gem "alfred-workflow"
Now we can install the template workflow, we just type:
$ rake install
or if you are using Dropbox sync as mentioned before, you can type:
$ rake dbxinstall
this will create a soft link in the right place, for my case, it just execute:
ln -sf /Users/luisleo/Software/AlfredWorkflow/alfred2-ascii-translator/workflow /Users/luisleo/Dropbox/Alfred/Alfred.alfredpreferences/workflows/me.ytliu.alfred2-ascii-translator`
Then when you open the Alfred Preference > Workflow
, you can see a new workflow added:
Here you can double click it to change some of the information like name, description and so on:
You can also double click the panel with “test feedback”, to see the keywords which can trigger the workflow:
You can also change the icon of your workflow. For my example, I just change it to what I need:
You can see that in the Script, the content is /usr/bin/ruby ./main.rb {query}
, which means when triger this action, it will execute this script. Now let’s see what happens in the main.rb
located in ascii
folder:
#!/usr/bin/env ruby# encoding: utf-8require "./bundle/bundler/setup"require "alfred"Alfred.with_friendly_error do |alfred| fb = alfred.feedback # add an arbitrary feedback fb.add_item({ :uid => "" , :title => "Just a Test" , :subtitle => "feedback item" , :arg => "A test feedback Item" , :valid => "yes" , }) if ARGV[0].eql? "failed" alfred.with_rescue_feedback = true raise Alfred::NoBundleIDError, "Wrong Bundle ID Test!" end puts fb.to_xmlend
From this code, you can see that all code are put in the block:
Alfred.with_friendly_error do |alfred|end
The input parameters can be retrieved from ARGV
. If we want to output something, we can use the fb.add_item
API:
# add an arbitrary feedbackfb.add_item({ :uid => "" , :title => "Just a Test" , :subtitle => "feedback item" , :arg => "A test feedback Item" , :valid => "yes" ,})puts fb.to_xml
So when you open Alfred, input test feedback
, you can see like this:
That’s quite simple.
So here come to my ASCII Translator:
#!/usr/bin/env ruby# encoding: utf-8require 'rubygems' unless defined? Gem # rubygems is only needed in 1.8require "./bundle/bundler/setup"require "alfred"def show_chars(fb, result) fb.add_item({ :uid => "", :title => "#{result}", :subtitle => "", :arg => "", :valid => "yes", })endspecial_ascii = ['NUL', 'SOH', 'STX', 'ETX', 'EOT', 'ENQ', 'ACK', 'BEL', 'BS', 'TAB', 'LF', 'VT', 'FF', 'CR', 'SO', 'SI', 'DLE', 'DC1', 'DC2', 'DC3', 'DC4', 'NAK', 'SYN', 'ETB', 'CAN', 'EM', 'SUB', 'ESC', 'FS', 'GS', 'RS', 'US']special_ascii_7f = 'del'Alfred.with_friendly_error do |alfred| alfred.with_rescue_feedback = true fb = alfred.feedback type = ARGV[0] if (type =~ /[d|h|c]/) == nil raise Alfred::InvalidFormat, "Usage: ascii [d|h|c] args" end if type == 'd' query = ARGV[1..-1].map(&:to_i) elsif type == 'h' query = ARGV[1..-1].map(&:hex) else query = ARGV[1..-1].join(" ") end result = Array.new if type == 'c' result = query.bytes.map { |c| "0x#{c.to_s(16)}" } else query.each do |q| if q < 0x20 result << special_ascii[q] elsif q == 0x7f result << special_ascii_7f elsif q < 0x7f result << q.chr else result << 'undefined' end end end for i in (0..result.size/10) show_chars(fb, result[i*10..[result.size-1, i*10+9].min].join(" ").strip) end puts fb.to_xmlend
If you can read ruby, you can surely read my code. Here I just don’t explain, you can see the README in github page, to have a idea of how to use it.