Skip to content
This repository was archived by the owner on Dec 15, 2022. It is now read-only.
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
36 changes: 34 additions & 2 deletions lib/bookmarks.coffee
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
_ = require 'underscore-plus'
{$} = require 'atom-space-pen-views'
{CompositeDisposable} = require 'atom'

module.exports =
Expand All @@ -18,6 +19,12 @@ class Bookmarks
@markerLayer ?= @editor.addMarkerLayer(markerLayerOptions)
@decorationLayer = @editor.decorateMarkerLayer(@markerLayer, {type: 'line-number', class: 'bookmarked'})
@disposables.add @editor.onDidDestroy(@destroy.bind(this))
@createWrapIcon()

createWrapIcon: ->
wrapIcon = document.createElement('div')
wrapIcon.classList.add('bookmark-wrap-icon')
@wrapIcon = $(wrapIcon)

destroy: ->
@deactivate()
Expand Down Expand Up @@ -61,6 +68,19 @@ class Bookmarks
else
atom.beep()

showWrapIcon: (icon) ->
editorView = atom.views.getView(@editor)
return unless editorView?.parentNode?

# Attach to the parent of the active editor, that way we can position it
# correctly over the active editor.
editorView.parentNode.appendChild(@wrapIcon[0])

# FIXME: This animation should be in CSS
@wrapIcon.attr('class', "bookmark-wrap-icon #{icon}").fadeIn()
clearTimeout(@wrapTimeout)
@wrapTimeout = setTimeout (=> @wrapIcon.fadeOut()), 1000

getPreviousBookmark: (bufferRow) ->
markers = @markerLayer.getMarkers()
return null unless markers.length
Expand All @@ -70,7 +90,13 @@ class Bookmarks
if marker.getBufferRange then marker.getBufferRange().start.row else marker

bookmarkIndex--
bookmarkIndex = markers.length - 1 if bookmarkIndex < 0

if bookmarkIndex < 0
if atom.config.get('bookmarks.wrapBuffer')
@showWrapIcon('icon-move-down')
bookmarkIndex = markers.length - 1
else
null

markers[bookmarkIndex]

Expand All @@ -83,7 +109,13 @@ class Bookmarks
if marker.getBufferRange then marker.getBufferRange().start.row else marker

bookmarkIndex++ if markers[bookmarkIndex] and markers[bookmarkIndex].getBufferRange().start.row is bufferRow
bookmarkIndex = 0 if bookmarkIndex >= markers.length

if bookmarkIndex >= markers.length
if atom.config.get('bookmarks.wrapBuffer')
@showWrapIcon('icon-move-up')
bookmarkIndex = 0
else
null

markers[bookmarkIndex]

Expand Down
12 changes: 12 additions & 0 deletions lib/main.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,14 @@ editorsBookmarks = null
disposables = null

module.exports =

config:
wrapBuffer:
title: 'Wrap Buffer'
description: 'When enabled, jumping to next or previous bookmark can wrap around the buffer.'
type: 'boolean'
default: true

activate: (bookmarksByEditorId) ->
editorsBookmarks = []
bookmarksView = null
Expand Down Expand Up @@ -35,6 +43,10 @@ module.exports =
bookmarks.deactivate() for bookmarks in editorsBookmarks
disposables.dispose()

getBookmarkForEditor: (editor) ->
for bookmark in editorsBookmarks
return bookmark if bookmark.editor.id is editor.id

serialize: ->
bookmarksByEditorId = {}
for bookmarks in editorsBookmarks
Expand Down
59 changes: 57 additions & 2 deletions spec/bookmarks-view-spec.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -217,7 +217,8 @@ describe "Bookmarks package", ->
editor.setSelectedBufferRanges([[[8, 4], [10, 0]]])
atom.commands.dispatch editorElement, 'bookmarks:toggle-bookmark'

it "jump-to-next-bookmark finds next bookmark", ->
it "jump-to-next-bookmark finds next bookmark with wrapping", ->
editor.config.set('bookmarks.wrapBuffer', true)
editor.setCursorBufferPosition([0, 0])

atom.commands.dispatch editorElement, 'bookmarks:jump-to-next-bookmark'
Expand All @@ -234,7 +235,8 @@ describe "Bookmarks package", ->
atom.commands.dispatch editorElement, 'bookmarks:jump-to-next-bookmark'
expect(editor.getLastCursor().getBufferPosition()).toEqual [2, 0]

it "jump-to-previous-bookmark finds previous bookmark", ->
it "jump-to-previous-bookmark finds previous bookmark with wrapping", ->
editor.config.set('bookmarks.wrapBuffer', true)
editor.setCursorBufferPosition([0, 0])

atom.commands.dispatch editorElement, 'bookmarks:jump-to-previous-bookmark'
Expand All @@ -251,6 +253,59 @@ describe "Bookmarks package", ->
atom.commands.dispatch editorElement, 'bookmarks:jump-to-previous-bookmark'
expect(editor.getLastCursor().getMarker().getBufferRange()).toEqual [[8, 4], [10, 0]]

it "jump-to-next-bookmark locks without wrapping", ->
editor.config.set('bookmarks.wrapBuffer', false)
editor.setCursorBufferPosition([0, 0])

atom.commands.dispatch editorElement, 'bookmarks:jump-to-next-bookmark'
expect(editor.getLastCursor().getBufferPosition()).toEqual [2, 0]

atom.commands.dispatch editorElement, 'bookmarks:jump-to-next-bookmark'
expect(editor.getLastCursor().getMarker().getBufferRange()).toEqual [[8, 4], [10, 0]]

atom.commands.dispatch editorElement, 'bookmarks:jump-to-next-bookmark'
expect(atom.beep.callCount).toBe 1

editor.setCursorBufferPosition([11, 0])

atom.commands.dispatch editorElement, 'bookmarks:jump-to-next-bookmark'
expect(atom.beep.callCount).toBe 2

it "jump-to-previous-bookmark locks without wrapping", ->
editor.config.set('bookmarks.wrapBuffer', false)
editor.setCursorBufferPosition([11, 0])

atom.commands.dispatch editorElement, 'bookmarks:jump-to-previous-bookmark'
expect(editor.getLastCursor().getMarker().getBufferRange()).toEqual [[8, 4], [10, 0]]

atom.commands.dispatch editorElement, 'bookmarks:jump-to-previous-bookmark'
expect(editor.getLastCursor().getBufferPosition()).toEqual [2, 0]

atom.commands.dispatch editorElement, 'bookmarks:jump-to-previous-bookmark'
expect(atom.beep.callCount).toBe 1

editor.setCursorBufferPosition([0, 0])

atom.commands.dispatch editorElement, 'bookmarks:jump-to-previous-bookmark'
expect(atom.beep.callCount).toBe 2

it "shows an icon when editor wraps around", ->
editor.config.set('bookmarks.wrapBuffer', true)
editor.setCursorBufferPosition([0, 0])
wrapIcon = bookmarks.getBookmarkForEditor(editor).wrapIcon

expect(wrapIcon).not.toBeVisible()
atom.commands.dispatch editorElement, 'bookmarks:jump-to-next-bookmark'
atom.commands.dispatch editorElement, 'bookmarks:jump-to-next-bookmark'
expect(wrapIcon).not.toBeVisible()
atom.commands.dispatch editorElement, 'bookmarks:jump-to-next-bookmark'
expect(wrapIcon).toBeVisible()
expect(wrapIcon).toHaveClass 'icon-move-up'

atom.commands.dispatch editorElement, 'bookmarks:jump-to-previous-bookmark'
expect(wrapIcon).toBeVisible()
expect(wrapIcon).toHaveClass 'icon-move-down'

describe "browsing bookmarks", ->
it "displays a select list of all bookmarks", ->
editor.setCursorBufferPosition([0])
Expand Down
32 changes: 32 additions & 0 deletions styles/bookmarks.less
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
@import "octicon-utf-codes.less";
@import "syntax-variables";

atom-text-editor,
atom-text-editor::shadow {
Expand All @@ -19,3 +20,34 @@ atom-text-editor::shadow {
}
}
}

.bookmark-wrap-icon {
@wrap-size: @font-size * 10;

display: none;
position: absolute;

// These are getting placed in the DOM as a pane item, so override the pane
// item positioning styles. :/
top: 50% !important;
left: 50% !important;
right: initial !important;
bottom: initial !important;

margin-top: @wrap-size * -0.5;
margin-left: @wrap-size * -0.5;

background: fadeout(darken(@syntax-background-color, 4%), 55%);
border-radius: @component-border-radius * 2;
text-align: center;
pointer-events: none;
&:before {
// Octicons look best in sizes that are multiples of 16px
font-size: @wrap-size - mod(@wrap-size, 16px) - 32px;
line-height: @wrap-size;
height: @wrap-size;
width: @wrap-size;
color: @syntax-text-color;
opacity: .5;
}
}