Sublime Forum

Displaying current function in the statusbar

#1

Is there a way to display the current function in the statusbar? There are times where Iā€™m jumping between parts of a file and it would be handy to know which function Iā€™m currently working within.

If thatā€™s not currently available, how hard would it be to make a plugin that does this?

1 Like

#2

itā€™s not currently possible but can be done very easily with a plugin. If youā€™re looking to make it yourself, hereā€™s ST2ā€™s api: http://www.sublimetext.com/docs/2/api_reference.html

0 Likes

#3

Iā€™m not that familiar with Python, but maybe this would be a good reason to get into it some more. Itā€™s going to be slow going, but I may have the plugin ready by the end of the year. :smiley:

0 Likes

#4

Sounds good. If you need help, just ask

0 Likes

#5

OK, first question. Iā€™ve figured out how to display a string in the statusbar (easiest part of the plugin), but Iā€™m completely lost on how to gather functions for the given view. Iā€™d have to figure out the language and then scan for functions based on that language.

Would it be possible to piggyback on SublimeCodeIntel somehow? Keep in mind Iā€™m a complete Python noob.

0 Likes

#6

Since youā€™re new to Python, donā€™t try to go big. It doesnā€™t have to work with every language right away. What language do you use primarily?

0 Likes

#7

Right now Iā€™m mostly concerned with JavaScript and PHP.

0 Likes

#8

So I did some playing around and made this: [code]import sublime, sublime_plugin

class FunctionInStatusListener(sublime_plugin.EventListener):
def on_deactived(self,view):
erase_status(ā€˜function nameā€™)
def on_selection_modified(self, view):
sel = view.sel()[0]
functionRegs = view.find_by_selector(ā€˜entity.name.function.jsā€™)
for r in reversed(functionRegs):
if r.a < sel.a:
view.set_status(ā€˜function nameā€™, view.substrĀ®)
break[/code]

It only works for javascript at the moment and is very hackish but you can play around with it. Iā€™m going to bed

0 Likes

#9

Very nice and very much appreciated! I took what you started and changed it to:

[code]import sublime, sublime_plugin

class FunctionInStatusListener(sublime_plugin.EventListener):
def on_deactived(self, view):
view.erase_status(ā€˜function nameā€™)

def on_close(self, view):
    view.erase_status('function name')

def on_activated(self, view):
    cf = self.get_current_function(view)
    if cf is None:
        view.erase_status('function name')
    else:
        view.set_status('function name', 'Function: ' + cf)

def on_selection_modified(self, view):
    cf = self.get_current_function(view)
    if cf is None:
        view.erase_status('function name')
    else:
        view.set_status('function name', 'Function: ' + cf)

def get_current_function(self, view):
    sel = view.sel()[0]
    functionRegs = view.find_by_selector('entity.name.function')
    cf = None
    for r in reversed(functionRegs):
        if r.a < sel.a:
            cf = view.substr(r)
            break

    return cf

[/code]

That seems to work for JS, PHP and Python for me. Itā€™s rough, but it does the job well enough for me!

0 Likes

#10

Very nice nizur - I can see me using some of this code in my own plugin now to link todoā€™s to function names!

0 Likes

#11

Feel free to use any of the code, tanepiper, since I just built off of C0D312ā€™s example. Iā€™m a complete Python noob too, so the code could be better Iā€™m sure.

0 Likes

#12

Thanks for making this! Iā€™ve been wanting this ever since switching to ST2 last summer.

0 Likes

#13

docs.python.org/library/bisect.html

0 Likes

#14

on_selection_modified is a listener you should try to avoid.

Add a print and look into the console, you will notice this listener is dispatched hundred of times when selecting big portions of text making the editor to crawl.

I suggest you listen the click event. Inspired on your code I use this:

ā€¦\Sublime Text 2\Packages\User\Default.sublime-mousemap


	{
		"button": "button1", "count": 1,
		"press_command": "drag_select",
		"command": "status_bar_function"
	}
]

ā€¦\Sublime Text 2\Packages\User\status_bar_function.py

[code]import sublime_plugin

class StatusBarFunctionCommand(sublime_plugin.TextCommand):
def run(self, edit):
view = self.view
region = view.sel()[0]
functionRegs = view.find_by_selector(ā€˜entity.name.functionā€™)
for r in reversed(functionRegs):
if r.a < region.a:
view.set_status(ā€˜functionā€™, view.substrĀ®)
return
view.erase_status(ā€˜functionā€™)[/code]

0 Likes

#15

I love this ā€“ you should package it up as a full-blown plug-in! Itā€™s one of the things I missed most after moving over from Notepad++

0 Likes

#16

github.com/SublimeText/CurrentFunction

Feel free to improve it.

0 Likes

#17

Ironically, I created github.com/akrabat/SublimeFunctionNameDisplay Saturday tooā€¦

Regards,

Robā€¦

0 Likes

#18

Good. Letā€™s join forces =) using your package.

0 Likes

#19

:smile:

Thanks for the updates. Iā€™m learning more about ST2 plugin development just by looking at your code!

Regards,

Robā€¦

0 Likes

#20

Nice, Iā€™d like to expand this to css selectors as well. Especially when in scss files, the nesting can get out of control!

[quote=ā€œnizurā€]Very nice and very much appreciated! I took what you started and changed it to:

[code]import sublime, sublime_plugin

class FunctionInStatusListener(sublime_plugin.EventListener):
def on_deactived(self, view):
view.erase_status(ā€˜function nameā€™)

def on_close(self, view):
    view.erase_status('function name')

def on_activated(self, view):
    cf = self.get_current_function(view)
    if cf is None:
        view.erase_status('function name')
    else:
        view.set_status('function name', 'Function: ' + cf)

def on_selection_modified(self, view):
    cf = self.get_current_function(view)
    if cf is None:
        view.erase_status('function name')
    else:
        view.set_status('function name', 'Function: ' + cf)

def get_current_function(self, view):
    sel = view.sel()[0]
    functionRegs = view.find_by_selector('entity.name.function')
    cf = None
    for r in reversed(functionRegs):
        if r.a < sel.a:
            cf = view.substr(r)
            break

    return cf

[/code]

That seems to work for JS, PHP and Python for me. Itā€™s rough, but it does the job well enough for me![/quote]

0 Likes