all repos — h3rald @ 9c7ff41431c5a1e522059b28e53607ca14a04d48

The sources of https://h3rald.com

content/articles/real-world-rawline-usage.textile

 1
 2
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
 100
 101
 102
 103
 104
 105
 106
 107
 108
 109
 110
 111
 112
 113
 114
 115
 116
 117
 118
 119
 120
 121
 122
 123
 124
 125
 126
 127
 128
 129
 130
 131
 132
 133
 134
 135
 136
 137
 138
 139
 140
 141
----- 
permalink: real-world-rawline-usage
filters_pre: 
- erb
- redcloth
title: Real-world Rawline usage
comments: 
- :date: 
  :author: gabriel
  :url: http://tagaholic.me
  :id: 2698
  :body: |-
    Nice work! Loving the irb script. For anyone unsure of how to add keybindings to the above irb script, try this:
    
    editor = Rawline.editor
    #move to beginning of line
    editor.bind(:ctrl_a) { editor.move_left while (!editor.line.bol?) }
    # move to end of line
    editor.bind(:ctrl_e) { editor.move_right while (!editor.line.eol?) }
- :date: 
  :author: gabriel
  :url: http://tagaholic.me
  :id: 2699
  :body: |
    uggh, that last bit should read:
    
    editor = Rawline.editor
    
    editor.bind(:ctrl_a) { editor.move_left while (!editor.line.bol?) }
     #move to beginning of line
    
    editor.bind(:ctrl_e) { editor.move_right while (!editor.line.eol?) }
    #move to end of line

- :date: 
  :author: Fabio Cevasco
  :url: http://www.h3rald.com
  :id: 2700
  :body: |-
    Yep, that's it! Thanks Gabriel for pointing it out!
    
    I'm glad you're enjoying using RawLine.
date: 2009-03-07 04:54:00 +01:00
tags: 
- ruby
- rawline
type: article
toc: true
-----
So I finally decided to update "RawLine":/rawline last week, and I added a more Readline-like API. When I first started the project, I was determined _not_ to do that, because the current Readline wrapper shipped with Ruby is not very Ruby-ish: it's a wrapper, after all!

The good thing of having a new API compatible with Readline is that now people can use RawLine in their Readline-powered scripts, with very minor modifications.

Let's have a look at some examples (they are also shipped with "Rawline v0.3.1":http://rubyforge.org/projects/rawline):
h3. Rush

"Rush":http://rush.heroku.com is an excellent gem which provides a cross-platform shell environment, entirely written in Ruby.
Being a shell, it obviously uses Readline for tab completion, and that does the job on Linux. On Windows though, things aren't that easy: 

* text gets garbled if you write long lines
* you can't type certain characters if they use some key modifiers like <RIGHT-ALT>, etc.

RawLine doesn't have these problems (that's the very reason why I created it), so here's a simple script which launches a Rawline-enabled Rush shell:

<% highlight :ruby do %>
require 'rubygems'
require 'rush'
require 'rawline'

class RawlineRush < Rush::Shell

	def initialize
		Rawline.basic_word_break_characters = "" 
		Rawline.completion_proc = completion_proc
		super
	end

	def run
		loop do
			cmd = Rawline.readline('rawline_rush> ')
			finish if cmd.nil? or cmd == 'exit'
			next if cmd == ""
			Rawline::HISTORY.push(cmd)
			execute(cmd)
		end
	end
end

shell = RawlineRush.new.run
<% end %>

What happens here? Nothing much really, all I had to do was:

# Derive a new class from Rush::Shell
# Set <code>Rawline.basic_word_break_characters</code> to the same value used in the original Rush code
# Set <code>Rawline.completion_proc</code> to _the same_ completion Proc used in the original Rush code
# Rewrite the original <code>run</code> replacing <code>Readline</code> with <code>Rawline</code>

And it works as it was intended to, i.e. typing <code>root['b<TAB></code> will expand to <code>root['bin/</code>, etc.
Note that I didn't write the completion Proc from scratch: it was already there.

h3. IRB

After trying out Rush, the next logical step was trying IRB itself: I could never use it properly on Windows, and that was really frustrating.
After a few minutes trying to figure out how to start IRB programmatically, I quickly came up with a similar example:

<% highlight :ruby do %>
require 'irb'
require 'irb/completion'
require 'rubygems'
require 'rawline'

Rawline.basic_word_break_characters= " \t\n\"\\'`><;|&{(" 
Rawline.completion_append_character = nil
Rawline.completion_proc = IRB::InputCompletor::CompletionProc

class RawlineInputMethod < IRB::ReadlineInputMethod
	include Rawline
	def gets
		if l = readline(@prompt, false)
			HISTORY.push(l) if !l.empty?
			@line[@line_no += 1] = l + "\n"
		else
			@eof = true
			l
		end
	end
end

module IRB
	@CONF[:SCRIPT] = RawlineInputMethod.new
end
IRB.start
<% end %>

In this case, Rawline is included in the <code>RawlineInputMethod</code> class, derived from the original <code>ReadlineInputMethod</code> class, i.e. the class IRB uses to define (guess...) how to input characters.
Again, all I had to do was set a few Rawline variables to match the ones used in Readline, and then redefine the function used to get characters. All done. 

It works as expected (only with inline completion, of course): typing <code>"test".ma<TAB></code> will give you <code>"test".map</code>, <code>"test".match</code>, etc.

You also get all Rawline key mappings for free (CTRL-K to clear the line, CTRL-U and CTRL-R to undo and redo, etc.), and you can define your own.