So I’m an avid vim user. I just wanted to write this down to remind myself, or
as Gary Bernhardt expresses it
Store it into my muscle memory!
Vim have registers. So when ever you perform an action of cut, paste, copy,
the selection is stored in a register.
Chose your register
You chose a register with "<name of register> and from there you can
do your motion, yank or whatever action you desire.
List your registers
You can list your register content with
:reg
The unnamed register ""
This is the default register, and vim will use this if you don’t specify a
register.
The named register "a--"z
Vim has a named register for each of the letters in the alphabet. So you can
"ad, "ay, or paste "ap
The /dev/null register "_
Sometimes you don’t want to store the text you manipulate, if you send it to
"_ it will not be stored.
The system clipboard register "+
This will store the text in the default X11 clipboard, pretty handy!
The selection register "*
This will store the text in the X11 selection clipboard, pretty handy! Note this will be the same as the system clipboard on windows or OSX, since there is only one clipboard.
The expression register "=
This register is different, since vim drops into commandline mode, and reads the input from the script you execute.
And the rest
Here are the rest of the registers:
Register
Content
"#
Alternate file
"%
Current file
"/
Last search pattern
":
Last Ex command
".
Last inserted text
I hope you’ll enjoy some more productivity in vim using registers!
I’ve wanted to dive into Elastic search and see what it does for sometime. Mostly to see how it was working with it.
Search Basics
When you first dive into search, there’s a couple of concepts you need to know about.
Documents
We denormalize our data into documents. Typical use cases for applying a search engine is on heavily normalized data, that needs to be combined into arbitrary queries, that would make ordinary sql statements too slow or complex, thus joining multiple tables, to only return a few columns.
Other usecases could be fulltext search or geospatial data. Documents are represented by JSON, which makes it a delight to work with.
The index
Documents are stored in an index. The index is what we search in. As the name state, it is fast to lookup documents in it. In Eleastic Search, the index is a lucene based index. The greater part of the index is typically loaded into memory, but persisted to disc at index time. So it can be reloaded in case of a server failure.
The schema
The document structure of the index is defined by a schema. In Elastic Search the schema is dynamic, so it’s possible to virtually throw anything at it.
In other lucene based search engines i.e. Solr, the schema is static and singular to the server instance. This means the server will have to be reloaded in order for a schema change to take place, and only one index is served. This clearly has its disadvantages.
Te have some structure to the index, we provide a mappings. Which basically define the data types our document should consist of.
Here I’ve listed an entry for one of the documents.
{"_index":"ycombinator","_type":"items","_id":"s6T7pwLNS8y1r4aUQXsoEA","_score":1.0,"_source":{"identifier":"7375376","author":"summerdown2","content":"Very addictive and lots of fun :)","link":"item?id=7375376","points":null,"parent":7373566}}
Indexes, Shards, Replica, Nodes, Clusters
Elastic Search operates with multiple indexes. A single index is made of shards, which can be scattered over multiple nodes in a cluster. Each shard can have a replica, which is an exact copy of a shard. This is used to enhance search performance, and as duplication in case of failure.
Indexes support basic create and delete operations on the fly.
Indexing
So getting data into the search engine is actually a project on its own. Basically there are two ways of populating an index.
Push data to elastic search, when it is modified
Query the database for delta changes
The first strategy works nicely if you have a monolithic system of one. If you have multiple sub systems that interact with your data, it would make sense to query the database for deltas.
The indexing task for this project is querying the database, because faults might appear when parsing the ycombinator for data.
The interaction with ElasticSearch is wrapped in the Elastic class.
require'elasticsearch'classElasticincludeSingleton# This creates the index and types at# '/name/type/'# making the documents availabledefcreate_index(name,type,body)client.indexindex: name,type: type,body: bodyend# Adds documents of type items to the index ycombinatordefadd_item(body)create_index('ycombinator','items',body)end# Creates the ElasticSearch clientdefclientElasticsearch::Client.newlog: trueendend
Queries
Finding things again in the index is nicely done using the lucene syntax.
Basic syntax
http://localhost:9200/ycombinator/items/_search?q=<query>
Giving query the following:
author:gebe # Will return documents with author gebe
+author:gebe # Will make author=gebe mandatory for results
-author:gebe # Will make exclude author gebe from results
Querying throug the gem would add this to the Elastic class
Facets are a way of summerizing on the data in the index. Lets assume I want to find how many items an author have created, I could as the index to facet over authors.
I’ve gathered some of my lessons learned in this post. First of all I’m skipping the basics, since that’s covered just fine in the README.
Notes On Configuration
Remember to flip your rails server, when you do configuration changes. They will not be loaded on the fly in development.
Wrappers
Wrappers was one of the things I had to dig in to, before figuring out how they work. The documentation explains how to set them up, but not really how they work.
So a wrapper is a configuration set that tells simple_form, how to render the components your form use. But what does that mean?
Let’s look at a simple wrapper, looking something like this:
# Here the wrapper is applied to all of the elements of the form
<%=simple_form_for@profile,wrapper: :simpledo|f|%><%=f.input:first_name%><%end%>
# Here it is only applied to the single field
<%=simple_form_for@profiledo|f|%><%=f.input:first_name,wrapper: :simple%><%end%>
Yes yes, but what does it do? Well … It wraps. Our first_name input field friend from above, will be wrapped, like this
<divclass="form_field string required profile_first_name"><labelclass="string required control-label"for="profile_first_name">
First name<abbrtitle="required">*</abbr></label><inputclass="string required"id="profile_first_name"name="profile[first_name]"size="50"type="text"></div>
So there’s a lot going on, and simple_form is indeed a powerful ally in maintaning forms across an application.
You can even nest the wrappers.
Custom input
Custom input types goes into the app/inputs folder. They will be loaded by simple_form.
Let’s take a look at a simple example. I want to add a weight type, thus appending the text kg to the input field.
It is as simple as this
classWeightInput<SimpleForm::Inputs::NumericInputdefinputout=''out<<super# Render what the super class has to offerout<<template.content_tag(:span,I18n.t('simple_form.units.defaults.kg'))out.html_safeendend
You can build your output, prepending, appending and pretty much do what you like with the fields.
I created a gem for doing ctags on my ruby project files and gem dependencies. Basically it will find all ruby files in your project, and run ctags on them. Then it will dive into your Gemfile and trawl through the source files of each gem.
It will store tags in .tags and .gemtags respectively.