Blogged by Ujihisa. Standard methods of programming and thoughts including Clojure, Vim, LLVM, Haskell, Ruby and Mathematics written by a Japanese programmer. github/ujihisa

Thursday, June 30, 2011

Vanrb Lightning Talk Slides: Ruby and Vim

http://www.meetup.com/vancouver-ruby-rails/events/21277581/

structure

structure

RSense

A Ruby development toolset

  • Code completion
  • Type inspection
  • Definition jump

RSense code completion

a.rb

a = '123'
b = a.to_i
b.

rsense command

$ rsense code-completion --file=a.rb --location=3:2
completion: to_enum Object#to_enum Object METHOD
completion: succ! String#succ! String METHOD
completion: swapcase! String#swapcase! String METHOD
completion: instance_variable_defined? Object#instance_variable_defined? Object METHOD
...

Implementation

  • Front-end command bin/rsense
  • Back-end server process with Java&JRuby
  • Type-inference algorithm "modified-Cartesian Product Algorithm"

limitations

  • classes in the buffer
  • 1.8 built-in libraries
  • incorrect syntax
  • evals and exceptions

Vim

Vim

Vim

Vim and me

  • fullscreen MacVim
  • vimshell (no other terminals)
  • neocomplcache
  • unite
  • quickrun

RSense built-in Vim plugin

User-defined completion <C-x><C-u>

a = '123'
b = a.to_i
b._

Insert-mode completions in general

  • <C-n> Keyword
  • <C-x><C-f> File name
  • <C-x><C-s> English spelling
  • <C-x><C-o> Omni
  • <C-x><C-u> User-defined

neocomplcache

Insert-mode auto-completion plugin framework

  • No key mapping necessary
  • Integrates lots of completions

RSense as omni func

~/.vimrc

let g:rsenseUseOmniFunc = 1
let g:rsenseHome = expand('~/git/rsense')

let g:neocomplcache_omni_patterns = {}
let g:neocomplcache_omni_patterns.ruby = '[^. *\t]\.\w*\|\h\w*::'

one more thing

  • neco-: prefix for neocomplcache plugins
  • neco-rake: rake task completion

structure

structure

Sunday, June 12, 2011

String\#slice of Ruby in Vim script and Haskell

A Ruby example of String#[]

str = "Oh, this is a pen."
p str[/this is a (\w+)\./, 1]

The result is "pen". Since String#[] is just an alias of String#slice, (*1)

p str.slice(/this is a (\w+)\./, 1)

The result is completely same.

in Vim script

Vim script version needs two separate processes; getting the list of first-matched string itself and containing sub matches, and then getting the specific item.

let str = "Oh, this is a pen."
echo matchlist(str, 'this is a \(\w\+\)\.')[1]

(Added at Sun Jun 12 09:26:44 PDT 2011) thinca suggested that matchstr() with \zs and \ze is very handy, particularly because of the different behavior in the case when it didn't match.

let str = "Oh, this is a pen."
echo matchstr(str, 'this is a \zs\w\+\ze\.')

in Haskell

Haskell version needs three separate processes with Text.Regex.Posix.=~; it's almost same to Vim but the default =~ behaviour is to assume the regex object has "global" option, so you have to pick which match.

import Text.Regex.Posix ((=~))
main = do
  let str = "Oh this is a pen."
  print $ head (str =~ "this is a ([a-zA-Z_]*)" :: [[String]]) !! 1

(Added at Sun Jun 12 12:54:01 PDT 2011) The following code is another example; it's safe in runtime and also this supports Vim's \zs and \ze.

import Text.Regex.PCRE ((=~))
import Data.String.Utils (replace)
import Safe (headMay, atMay)
import Data.Maybe (fromMaybe)

matchstr :: String -> String -> String
matchstr expr pat =
  let x = replace "\\zs" "(" $ replace "\\ze" ")" pat in
  fromMaybe "" $ headMay (expr =~ x :: [[String]]) >>= \y -> atMay y 1

main = print $ matchstr "this is a pen" " \\zs\\w+\\ze"

in Clojure

(Added at Thu Mar 22 17:49:40 PDT 2012)

((re-find #"this is a (\w+)\." "Oh, this is a pen.") 1)
; "pen"
  • (*1) Precisely no. Try and check the differences between them without the second argument.

Followers