Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

rename refactor #641

Open
wants to merge 9 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions lib/misc/blocks.js
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,7 @@ export function getLocalContext (editor, row) {
const context = range ? editor.getTextInBufferRange(range) : ''
const startRow = range ? range[0][0] : undefined
return {
range,
context,
startRow
}
Expand Down
2 changes: 1 addition & 1 deletion lib/misc/words.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

import { Point, Range } from 'atom'

export const wordRegex = /[\u00A0-\uFFFF\w_!´\.]*@?[\u00A0-\uFFFF\w_!´]+/
const wordRegex = /[\u00A0-\uFFFF\w_!´\.]*@?[\u00A0-\uFFFF\w_!´]+/

/**
* Takes an `editor` and gets the word at current cursor position. If that is nonempty, call
Expand Down
4 changes: 4 additions & 0 deletions lib/package/commands.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,10 @@ module.exports =
@withInk ->
boot()
juno.runtime.evaluation.toggleDocs()
'julia-client:rename-refactor': =>
@withInk ->
boot()
juno.runtime.refactor.renameRefactor()
# @NOTE: `'clear-workspace'` is now not handled by Atom.jl
# 'julia-client:reset-workspace': =>
# requireClient 'reset the workspace', ->
Expand Down
6 changes: 4 additions & 2 deletions lib/runtime.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ module.exports =
debuginfo: require './runtime/debuginfo'
formatter: require './runtime/formatter'
goto: require './runtime/goto'
urihandler: require './runtime/urihandler'
refactor: require './runtime/refactor'

activate: ->
@subs = new CompositeDisposable()
Expand All @@ -29,7 +31,7 @@ module.exports =
consumeInk: (ink) ->
@evaluation.ink = ink
@frontend.ink = ink
for mod in [@console, @debugger, @profiler, @linter, @goto, @outline]
for mod in [@console, @debugger, @profiler, @linter, @goto, @outline, @urihandler, @refactor]
mod.activate(ink)
for mod in [@workspace, @plots]
mod.ink = ink
Expand Down Expand Up @@ -60,4 +62,4 @@ module.exports =
@subs.add(datatipDisposable)
datatipDisposable

handleURI: require './runtime/urihandler'
handleURI: (parsedURI) -> @urihandler.handleURI parsedURI
2 changes: 1 addition & 1 deletion lib/runtime/goto.js
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ class Goto {
// module context
const currentModule = modules.current()
const mod = currentModule ? currentModule : 'Main'
const text = editor.getText() // buffer text that will be used for fallback entry
const text = editor.getText() // will be used as a fallback entry, e.g.: when in Main module

gotoSymbol({
word,
Expand Down
7 changes: 5 additions & 2 deletions lib/runtime/profiler.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ var {loadProfileTrace, saveProfileTrace} = client.import({msg: ['loadProfileTrac

export function activate (ink) {
pane = ink.PlotPane.fromId('Profile')
pane.getTitle = () => {return 'Profiler'}
pane.setTitle('Profiler')
subs = new CompositeDisposable()

subs.add(client.onDetached(() => clear()))
Expand All @@ -24,7 +24,10 @@ export function activate (ink) {
pane.ensureVisible({
split: atom.config.get('julia-client.uiOptions.layouts.profiler.split')
})
pane.show(new ink.Pannable(profile, {zoomstrategy: 'width', minScale: 0.5}))
pane.show(new ink.Pannable(profile, {
zoomstrategy: 'width',
minScale: 0.5
}))
}
})

Expand Down
101 changes: 101 additions & 0 deletions lib/runtime/refactor.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
/** @babel */

import { client } from '../connection'
import modules from './modules'
import { getWordRangeAtBufferPosition, isValidWordToInspect } from '../misc/words'
import { getLocalContext } from '../misc/blocks'

const renamerefactor = client.import('renamerefactor')
const wordRegexWithoutDotAccessor = /@?[\u00A0-\uFFFF\w_!´]+/

class Refactor {
activate (ink) {
this.ink = ink
}

renameRefactor () {
const editor = atom.workspace.getActiveTextEditor()
const bufferPosition = editor.getCursorBufferPosition()

if (!client.isActive()) return

const range = getWordRangeAtBufferPosition(editor, bufferPosition, {
wordRegex: wordRegexWithoutDotAccessor
})
if (range.isEmpty()) return
const oldWord = editor.getTextInBufferRange(range)
if (!isValidWordToInspect(oldWord)) return

const rangeFull = getWordRangeAtBufferPosition(editor, bufferPosition)
const fullWord = editor.getTextInBufferRange(rangeFull)

this.ink.showBasicModal([{
name: 'Rename',
defaultText: oldWord,
message: `Enter an new name to which \`${oldWord}\` will be renamed.`
}]).then(items => {
// check the new name is a valid identifier
const newWord = items['Rename']
if (!isValidWordToInspect(newWord) || newWord.match(wordRegexWithoutDotAccessor) != newWord) {
atom.notifications.addWarning('Julia Client: Rename Refactor', {
description: `\`${newWord}\` isn't a valid identifier`
})
return
}

// local context
const { column, row } = bufferPosition
const { range, context, startRow } = getLocalContext(editor, row)

// module context
const currentModule = modules.current()
const mod = currentModule ? currentModule : 'Main'

renamerefactor({
oldWord,
fullWord,
newWord,
// local context
column: column + 1,
row: row + 1,
startRow,
context,
// module context
mod,
}).then(result => {
// local refactoring
if (result.text) {
editor.setTextInBufferRange(range, result.text)
}
if (result.success) {
atom.notifications.addSuccess('Julia Client: Rename Refactor', {
description: result.success,
dismissable: true
})
}
if (result.info) {
atom.notifications.addInfo('Julia Client: Rename Refactor', {
description: result.info,
dismissable: true
})
}
if (result.warning) {
atom.notifications.addWarning('Julia Client: Rename Refactor', {
description: result.warning,
dismissable: true
})
}
if (result.error) {
atom.notifications.addError('Julia Client: Rename Refactor', {
description: result.error,
dismissable: true
})
}
})
}).catch((err) => {
if (err) console.error(err)
})
}
}

export default new Refactor()
76 changes: 49 additions & 27 deletions lib/runtime/urihandler.js
Original file line number Diff line number Diff line change
@@ -1,37 +1,59 @@
"use babel"
/** @babel */

import { client } from '../connection'
import { docpane, views } from '../ui'

const { moduleinfo } = client.import({ rpc: ['moduleinfo'] })
const docs = client.import('docs')
const {
gotosymbol: gotoSymbol,
moduleinfo: moduleInfo
} = client.import({ rpc: [ 'gotosymbol', 'moduleinfo' ] })

export default function handleURI (parsedURI) {
const { query } = parsedURI
class URIHandler {
activate(ink) {
this.ink = ink
}

handleURI (parsedURI) {
const { query } = parsedURI

if (query.open) { // open a file
atom.workspace.open(query.file, {
initialLine: Number(query.line),
pending: atom.config.get('core.allowPendingPaneItems')
})
} else if (query.docs) { // show docs
const { word, mod } = query
docs({ word, mod }).then(result => {
if (result.error) return
const view = views.render(result)
docpane.processLinks(view.getElementsByTagName('a'))
docpane.ensureVisible()
docpane.showDocument(view, [])
})
} else if (query.moduleinfo){ // show module info
const { mod } = query
moduleinfo({ mod }).then(({ doc, items }) => {
items.map(item => {
docpane.processItem(item)
if (query.open) { // open a file
atom.workspace.open(query.file, {
initialLine: Number(query.line),
pending: atom.config.get('core.allowPendingPaneItems')
})
} else if (query.docs) { // show docs
const { word, mod } = query
docs({ word, mod }).then(result => {
if (result.error) return
const view = views.render(result)
docpane.processLinks(view.getElementsByTagName('a'))
docpane.ensureVisible()
docpane.showDocument(view, [])
})
const view = views.render(doc)
docpane.ensureVisible()
docpane.showDocument(view, items)
})
} else if (query.goto) {
const { word, mod } = query
gotoSymbol({
word,
mod
}).then(symbols => {
if (symbols.error) return
this.ink.goto.goto(symbols, {
pending: atom.config.get('core.allowPendingPaneItems')
})
})
} else if (query.moduleinfo){ // show module info
const { mod } = query
moduleInfo({ mod }).then(({ doc, items }) => {
items.map(item => {
docpane.processItem(item)
})
const view = views.render(doc)
docpane.ensureVisible()
docpane.showDocument(view, items)
})
}
}
}

export default new URIHandler()