Skip to content

Commit

Permalink
Clean & fix the code
Browse files Browse the repository at this point in the history
  • Loading branch information
cynddl committed Jan 4, 2015
1 parent 4fe6c10 commit 98421d4
Show file tree
Hide file tree
Showing 4 changed files with 68 additions and 49 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ This plugin for Sublime Text 3 allows you to analyse OCaml source code, autocomp

## Installation

First of all, be sure to have [merlin](https://github.com/the-lambda-church/merlin) installed.
First of all, be sure to have [merlin](https://github.com/the-lambda-church/merlin) installed. The current supported version of merlin is 2.0.

The shorter way of doing this is with [opam](opam.ocaml.org), an OCaml package manager:

Expand All @@ -20,7 +20,7 @@ For the moment (during development), sublime-text-merlin is not listed in the Pa

## Work in Progress

This is an initial port of the vim plugin of merlin. Buffers can be synchronised with merlin, but any edit need a full refresh between ST and merlin. Projects are not supported.
This is an initial port of the vim plugin of merlin. Buffers can be synchronised with merlin, but any edit needs a full refresh between ST and merlin. Projects are not supported.

If you want to use fully merlin with Sublime Text, fork this repository.

Expand Down
3 changes: 2 additions & 1 deletion merlin/helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,9 +59,10 @@ def merlin_pos(view, pos):

return view.text_point(pos['line'] - 1, pos['col'])


def clean_whitespace(text):
"""
Replace sequence of whitespaces by a single space
"""

return ' '.join(text.split()) # yes, it's a feature, HAHAHA
return ' '.join(text.split())
25 changes: 16 additions & 9 deletions merlin/process.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ class MerlinException(MerlinExc):
""" Standard exception. """
pass


class MerlinProcess(object):
"""
This class launches a merlin process and send/receive commands to
Expand Down Expand Up @@ -119,7 +120,7 @@ def reset(self, kind="auto", name=None):
self.find_use("ocamlbuild")
return r

def _parse_cursor(self,result):
def _parse_cursor(self, result):
""" Parser cursor values returned by merlin. """
position = result['cursor']
marker = result['marker']
Expand Down Expand Up @@ -148,14 +149,14 @@ def tell_source(self, content):

def seek_start(self):
""" Reset cursor to the beginning of the file. """
return self.send_cursor_command("seek","before",{'line': 1, 'col': 0})
return self.send_cursor_command("seek", "before", {'line': 1, 'col': 0})

def seek_marker(self):
"""
After satisfaying a tell marker, place the cursor immediately after the
marker.
"""
return self.send_cursor_command("seek","marker")
return self.send_cursor_command("seek", "marker")

def complete_cursor(self, base, line, col):
""" Return possible completions at the current cursor position. """
Expand All @@ -176,7 +177,7 @@ def find_use(self, *packages):
""" Find and load external modules. """
return self.send_command('find', 'use', packages)

def project():
def project(self):
"""
Returns a tuple
(dot_merlins, failures)
Expand Down Expand Up @@ -218,20 +219,26 @@ def sync_buffer(self, view):
# Path management
def add_build_path(self, path):
return self.send_command("path", "add", "build", path)

def add_source_path(self, path):
return self.send_command("path", "add", "source", path)

def remove_build_path(self, path):
return self.send_command("path", "remove", "build", path)

def remove_source_path(self, path):
return self.send_command("path", "remove", "source", path)

def list_build_path(self):
return self.send_command("path", "list", "build")

def list_source_path(self):
return self.send_command("path", "list", "source")

# File selection
def which_path(self, names):
return self.send_command("which", "path", names)

def which_with_ext(self, extensions):
return self.send_command("which", "with_ext", extensions)

Expand All @@ -242,16 +249,16 @@ def type_enclosing(self, line, col):

# Extensions management
def extension_list(self, crit=None):
if crit: # "enabled" | "disabled"
return self.send_command("extension","list",crit)
if crit in ['enabled', 'disabled']:
return self.send_command("extension", "list", crit)
else:
return self.send_command("extension","list")
return self.send_command("extension", "list")

def extension_enable(self, exts):
self.send_command("extension","enable",exts)
self.send_command("extension", "enable", exts)

def extension_disable(self, exts):
self.send_command("extension","disable",exts)
self.send_command("extension", "disable", exts)

def locate(self, line, col, ident="", kind="mli"):
if line is None or col is None:
Expand Down
85 changes: 48 additions & 37 deletions sublime-text-merlin.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
This module allows you to analyse OCaml source code, autocomplete and infer types while writing
"""

import subprocess
import functools
import sublime
import sublime_plugin
Expand All @@ -11,13 +10,15 @@
import sys

if sys.version_info < (3, 0):
from merlin.process import MerlinProcess, merlin_bin
from merlin.process import MerlinProcess
from merlin.helpers import merlin_pos, only_ocaml, clean_whitespace
else:
from .merlin.process import MerlinProcess, merlin_bin
from .merlin.process import MerlinProcess
from .merlin.helpers import merlin_pos, only_ocaml, clean_whitespace

running_process = None


def merlin_process(name):
global running_process
if running_process is None:
Expand All @@ -38,8 +39,8 @@ def run(self):
self.window.show_quick_panel(self.modules, self.on_done)

def on_done(self, index):
if index == -1: return
self.process.find_use(self.modules[index])
if index != -1:
self.process.find_use(self.modules[index])


class MerlinAddBuildPath(sublime_plugin.WindowCommand):
Expand Down Expand Up @@ -97,8 +98,8 @@ def run(self):
self.window.show_quick_panel(self.directories, self.on_done)

def on_done(self, index):
if index == -1: return
self.process.remove_build_path(self.directories[index])
if index != -1:
self.process.remove_build_path(self.directories[index])


class MerlinRemoveSourcePath(sublime_plugin.WindowCommand):
Expand All @@ -114,8 +115,8 @@ def run(self):
self.window.show_quick_panel(self.directories, self.on_done)

def on_done(self, index):
if index == -1: return
self.process.remove_source_path(self.directories[index])
if index != -1:
self.process.remove_source_path(self.directories[index])


class MerlinEnableExtension(sublime_plugin.WindowCommand):
Expand All @@ -131,8 +132,8 @@ def run(self):
self.window.show_quick_panel(self.extensions, self.on_done)

def on_done(self, index):
if index == -1: return
self.process.extension_enable([self.extensions[index]])
if index != -1:
self.process.extension_enable([self.extensions[index]])


class MerlinDisableExtension(sublime_plugin.WindowCommand):
Expand All @@ -148,16 +149,16 @@ def run(self):
self.window.show_quick_panel(self.extensions, self.on_done)

def on_done(self, index):
if index == -1: return
self.process.extension_disable([self.extensions[index]])
if index != -1:
self.process.extension_disable([self.extensions[index]])


class MerlinTypeEnclosing:
"""
Return type information around cursor.
"""

def __init__(self,view):
def __init__(self, view):
process = merlin_process(view.file_name())
process.sync_buffer_to_cursor(view)

Expand All @@ -180,8 +181,10 @@ def _item_region(self, item):

def _item_format(self, item):
text = item['type']
if item['tail'] == 'position': text = text + " (*tail-position*)"
if item['tail'] == 'call': text = text + " (*tail-call*)"
if item['tail'] == 'position':
text += " (*tail-position*)"
if item['tail'] == 'call':
text += " (*tail-call*)"
return clean_whitespace(text)

def _items(self):
Expand All @@ -199,6 +202,7 @@ def on_done(self, index):
sel.clear()
sel.add(self._item_region(self.enclosing[index]))


class MerlinTypeCommand(sublime_plugin.WindowCommand):
"""
Return type information around cursor.
Expand All @@ -207,6 +211,7 @@ def run(self):
enclosing = MerlinTypeEnclosing(self.view)
enclosing.show_panel()


class MerlinTypeMenu(sublime_plugin.TextCommand):
"""
Display type information in context menu
Expand All @@ -215,6 +220,7 @@ def run(self, edit):
enclosing = MerlinTypeEnclosing(self.view)
enclosing.show_menu()


def merlin_locate_result(result, window):
if isinstance(result, dict):
pos = result['pos']
Expand All @@ -226,11 +232,12 @@ def merlin_locate_result(result, window):
sel = view.sel()
sel.clear()
pos = merlin_pos(view, pos)
sel.add(sublime.Region(pos,pos))
sel.add(sublime.Region(pos, pos))
view.show_at_center(pos)
else:
sublime.message_dialog(result)


class MerlinLocateMli(sublime_plugin.WindowCommand):
"""
Locate definition under cursor
Expand All @@ -256,7 +263,7 @@ def run(self, edit):
self.window.show_input_panel("Enter name", "", self.on_done, None, None)

def kind(self):
return "mli"
return "mli"

def on_done(self, name):
view = self.window.active_view()
Expand All @@ -267,14 +274,17 @@ def on_done(self, name):
line, col = view.rowcol(pos[0].begin())
merlin_locate_result(process.locate(line + 1, col, ident=name), self.window)


class MerlinLocateMl(MerlinLocateMli):
def kind(self):
return "ml"


class MerlinLocateNameMl(MerlinLocateNameMli):
def kind(self):
return "ml"


class MerlinWhich(sublime_plugin.WindowCommand):
"""
Abstract command to quickly find a file.
Expand All @@ -291,10 +301,10 @@ def run(self):
self.window.show_quick_panel(self.files, self.on_done)

def on_done(self, index):
if index == -1: return
module_name = self.files[index]
modules = map(lambda ext: module_name + ext, self.extensions())
self.window.open_file(self.process.which_path(list(modules)))
if index != -1:
module_name = self.files[index]
modules = map(lambda ext: module_name + ext, self.extensions())
self.window.open_file(self.process.which_path(list(modules)))


class MerlinFindMl(MerlinWhich):
Expand All @@ -303,7 +313,7 @@ class MerlinFindMl(MerlinWhich):
"""

def extensions(self):
return [".ml",".mli"]
return [".ml", ".mli"]


class MerlinFindMli(MerlinWhich):
Expand All @@ -312,7 +322,7 @@ class MerlinFindMli(MerlinWhich):
"""

def extensions(self):
return [".mli",".ml"]
return [".mli", ".ml"]


class Autocomplete(sublime_plugin.EventListener):
Expand Down Expand Up @@ -427,19 +437,20 @@ def show_errors(self, view):
underlines = []

for e in errors:
pos_start = e['start']
pos_stop = e['end']
pnt_start = merlin_pos(view, pos_start)
pnt_stop = merlin_pos(view, pos_stop)
r = sublime.Region(pnt_start, pnt_stop)
line_r = view.full_line(r)
line_r = sublime.Region(line_r.a - 1, line_r.b)
underlines.append(r)

# Remove line and character number
message = e['message']

error_messages.append((line_r, message))
if 'start' in e and 'end' in e:
pos_start = e['start']
pos_stop = e['end']
pnt_start = merlin_pos(view, pos_start)
pnt_stop = merlin_pos(view, pos_stop)
r = sublime.Region(pnt_start, pnt_stop)
line_r = view.full_line(r)
line_r = sublime.Region(line_r.a - 1, line_r.b)
underlines.append(r)

# Remove line and character number
message = e['message']

error_messages.append((line_r, message))

self.error_messages = error_messages
flag = sublime.DRAW_OUTLINED
Expand Down

0 comments on commit 98421d4

Please sign in to comment.