Coder Social home page Coder Social logo

text-buffer's Introduction

Atom and all repositories under Atom will be archived on December 15, 2022. Learn more in our official announcement

Atom TextBuffer Core

CI

This is the core of the Atom text buffer, separated into its own module so its tests can be run headless. It handles the storage and manipulation of text and associated regions (markers).

text-buffer's People

Contributors

50wliu avatar aminya avatar arcanemagus avatar areksredzki avatar as-cii avatar benogle avatar bolinfest avatar captainjohnyappleseed avatar damieng avatar danielchatfield avatar darangi avatar daviwil avatar gosukiwi avatar hansonw avatar iolsen avatar jasonrudolph avatar joefitzgerald avatar kevinsawicki avatar kuychaco avatar leroix avatar maxbrunsfeld avatar mnquintana avatar peterdavehello avatar rafeca avatar sadick254 avatar smashwilson avatar t9md avatar torn4dom4n avatar vramana avatar zcbenz avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

text-buffer's Issues

Suggestion: Flag modified lines with whitespace-only changes

Atom neatly colours lines that've been added, removed or changed since the last commit:
screen shot 2016-03-13 at 8 25 35 pm

Looking at the classes applied to the line, though, it doesn't seem like there's any way to identify lines that've only been modified with whitespace:

screen shot 2016-03-13 at 8 27 24 pm

Having a .git-line-whitespace class would be helpful for theme authors wishing to target lines with cosmetic whitespace changes (the way git diff -w would). In my particular case, I wouldn't mind hiding the highlights completely, but as it is, I've no way of doing so with pure CSS.

Unexpected marker properties loss after reload/restart

I develop a package that highlights colors by scanning the buffer and creating markers for each colors found and I encounter a strange behavior since version 0.68 regarding buffer's markers and reload/restart.

I scan the buffer to find colors using a regexp, then I create a marker with some custom properties such the matching string and the css representation of the color. I try to take care of existing markers and only create new ones when needed, but it seems that after a first serialization of the buffer, some markers aren't properly restored, the marker doesn't hold the custom properties, not even the native one, I set a creation (such invalidation or persistence), BTW, setting persistent: false doesn't prevent the marker from being persisted.

The marker management is handled here : https://github.com/abe33/atom-color-highlight/blob/frozen_marker_example/lib/atom-color-highlight-model.coffee#L48

I log during my model creation a property I create on markers here: https://github.com/abe33/atom-color-highlight/blob/frozen_marker_example/lib/atom-color-highlight-model.coffee#L16

On the first run after clearing the storage files I get :

[undefined] atom-color-highlight-model.coffee:17
1 

No markers created, all is good.
Then I reload :

[undefined, "#F00", "#FF0000", "rgb(255, 0, 0)", "rgb(100%, 0%, 0%)", "rgba(255, 0, 0, 0.5)", "hsl(0, 100%, 50%)", "hsl(120, 100%, 50%)", "hsl(120, 100%, 25%)", "hsl(120, 100%, 75%)", "hsl(120, 50%, 50%)", "hsla(120, 100%, 50%, 1)", "hsla(120, 100%, 50%, 0.5)", "hsla(120, 100%, 50%, 0.1)", "#00ff00", "#00ff00", "#00ff00", "0xabcdef", "0x66abcdef", "0x11abcdef", "vec4(0.2, 0.4, 0.5, 1)", "vec4(0.2, 0.4, 0.5, 0.5)", "vec4(0.2, 0.4, 0.5, 0.1)"] atom-color-highlight-model.coffee:17
23

No problem here neither, the markers were properly restored with their custom properties.

Then I reload again:

[undefined, "#F00", "#FF0000", "rgb(255, 0, 0)", "rgb(100%, 0%, 0%)", "rgba(255, 0, 0, 0.5)", "hsl(0, 100%, 50%)", "hsl(120, 100%, 50%)", "hsl(120, 100%, 25%)", undefined, undefined, undefined, "hsla(120, 100%, 50%, 0.5)", "hsla(120, 100%, 50%, 0.1)", "#00ff00", "#00ff00", "#00ff00", "0xabcdef", "0x66abcdef", "0x11abcdef", "vec4(0.2, 0.4, 0.5, 1)", "vec4(0.2, 0.4, 0.5, 0.5)", "vec4(0.2, 0.4, 0.5, 0.1)"] atom-color-highlight-model.coffee:17
23 

As you can see here, three markers had lost their properties, always the same three markers each time I clear the storage. And, if I continue to reload and reload again, it start to get weirder. Sometimes more markers loses their state, but one reload later they have it again, or it's some other markers that have lost it, etc...

Do you have any clue on what's going on ?
Is it something in the way I create/manage the markers ?
In that case, why, when setting the persistent attribute to false, the markers are stille serialized ? Did I miss the point of the persistent attribute ?

Painfully slow buffer-update for large files

Problem description

If a large file is open in an atom editor window and it is reloaded for whatever reason, it will block the entire editor. This will happen for a painfully long time.

Very often I will have a large JSON file open and for one reason or another it will be reloaded, typically caused by a fs change, and the entire browser will be blocked for what is often a minute or more.

Today I finally performed a profile of the issue and nailed down the cause.
Here is the result for the reload of a relatively medium sized file (only ~6000 lines).
Profiling Result

Suggested changes

Short term

Give the user the option to diff the file or simply forego the ability to undo the reload if the file is large.

  • Reduces user frustration by eliminating unexpected behavior
  • Retains functionality if one wants it
  • Easy to implement, shouldn't take more than a couple LOC 👍

Long term

Somehow preserve undo-ability for massive files

Execution

Let me know if you like the sound of the short term solution, I'd be happy to implement it ASAP

`npm install` fails under Node 4.0.0

 01:57:26  dan@elise:~/stuff/text-buffer   master ✔ 
$ npm install
npm WARN package.json [email protected] No license field.
npm WARN installMany asserts.js was bundled with [email protected], but bundled package wasn't found in unpacked tree
npm WARN installMany fn.js was bundled with [email protected], but bundled package wasn't found in unpacked tree
npm WARN installMany observer.js was bundled with [email protected], but bundled package wasn't found in unpacked tree

> [email protected] install /Users/dan/stuff/text-buffer/node_modules/pathwatcher/node_modules/runas
> node-gyp rebuild

  CXX(target) Release/obj.target/runas/src/main.o
In file included from ../src/main.cc:1:
../../nan/nan.h:260:25: error: redefinition of '_NanEnsureLocal'
NAN_INLINE v8::Local<T> _NanEnsureLocal(v8::Local<T> val) {
                        ^
../../nan/nan.h:255:25: note: previous definition is here
NAN_INLINE v8::Local<T> _NanEnsureLocal(v8::Handle<T> val) {
                        ^
../../nan/nan.h:660:13: error: no member named 'smalloc' in namespace 'node'
    , node::smalloc::FreeCallback callback
      ~~~~~~^
../../nan/nan.h:671:12: error: no matching function for call to 'New'
    return node::Buffer::New(v8::Isolate::GetCurrent(), data, size);
           ^~~~~~~~~~~~~~~~~
/Users/dan/.node-gyp/4.0.0/src/node_buffer.h:31:40: note: candidate function not viable: no known conversion from
      'uint32_t' (aka 'unsigned int') to 'enum encoding' for 3rd argument
NODE_EXTERN v8::MaybeLocal<v8::Object> New(v8::Isolate* isolate,
                                       ^
/Users/dan/.node-gyp/4.0.0/src/node_buffer.h:43:40: note: candidate function not viable: 2nd argument ('const char *')
      would lose const qualifier
NODE_EXTERN v8::MaybeLocal<v8::Object> New(v8::Isolate* isolate,
                                       ^
/Users/dan/.node-gyp/4.0.0/src/node_buffer.h:28:40: note: candidate function not viable: requires 2 arguments, but 3
      were provided
NODE_EXTERN v8::MaybeLocal<v8::Object> New(v8::Isolate* isolate, size_t length);
                                       ^
/Users/dan/.node-gyp/4.0.0/src/node_buffer.h:36:40: note: candidate function not viable: requires 5 arguments, but 3
      were provided
NODE_EXTERN v8::MaybeLocal<v8::Object> New(v8::Isolate* isolate,
                                       ^
In file included from ../src/main.cc:1:
../../nan/nan.h:675:12: error: no viable conversion from 'v8::MaybeLocal<v8::Object>' to 'v8::Local<v8::Object>'
    return node::Buffer::New(v8::Isolate::GetCurrent(), size);
           ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/Users/dan/.node-gyp/4.0.0/deps/v8/include/v8.h:210:7: note: candidate constructor (the implicit copy constructor) not
      viable: no known conversion from 'v8::MaybeLocal<v8::Object>' to 'const v8::Local<v8::Object> &' for 1st
      argument
class Local {
      ^
/Users/dan/.node-gyp/4.0.0/deps/v8/include/v8.h:210:7: note: candidate constructor (the implicit move constructor) not
      viable: no known conversion from 'v8::MaybeLocal<v8::Object>' to 'v8::Local<v8::Object> &&' for 1st argument
class Local {
      ^
/Users/dan/.node-gyp/4.0.0/deps/v8/include/v8.h:214:13: note: candidate template ignored: could not match 'Local'
      against 'MaybeLocal'
  V8_INLINE Local(Local<S> that)
            ^
/Users/dan/.node-gyp/4.0.0/deps/v8/include/v8.h:326:13: note: candidate template ignored: could not match 'S *'
      against 'v8::MaybeLocal<v8::Object>'
  V8_INLINE Local(S* that)
            ^
In file included from ../src/main.cc:1:
../../nan/nan.h:682:26: error: no member named 'Use' in namespace 'node::Buffer'
    return node::Buffer::Use(v8::Isolate::GetCurrent(), data, size);
           ~~~~~~~~~~~~~~^
In file included from ../src/main.cc:1:
In file included from ../../nan/nan.h:24:
In file included from /Users/dan/.node-gyp/4.0.0/src/node.h:42:
/Users/dan/.node-gyp/4.0.0/deps/v8/include/v8.h:221:5: error: assigning to 'v8::Primitive *volatile' from incompatible
      type 'v8::Value *'
    TYPE_CHECK(T, S);
    ^~~~~~~~~~~~~~~~
/Users/dan/.node-gyp/4.0.0/deps/v8/include/v8.h:180:37: note: expanded from macro 'TYPE_CHECK'
    *(static_cast<T* volatile*>(0)) = static_cast<S*>(0);      \
                                    ^ ~~~~~~~~~~~~~~~~~~
../../nan/nan.h:413:12: note: in instantiation of function template specialization
      'v8::Local<v8::Primitive>::Local<v8::Value>' requested here
    return NanEscapeScope(NanNew(v8::Undefined(v8::Isolate::GetCurrent())));
           ^
../../nan/nan.h:397:30: note: expanded from macro 'NanEscapeScope'
# define NanEscapeScope(val) scope.Escape(_NanEnsureLocal(val))
                             ^
In file included from ../src/main.cc:1:
In file included from ../../nan/nan.h:24:
In file included from /Users/dan/.node-gyp/4.0.0/src/node.h:42:
/Users/dan/.node-gyp/4.0.0/deps/v8/include/v8.h:221:5: error: assigning to 'v8::Boolean *volatile' from incompatible
      type 'v8::Value *'
    TYPE_CHECK(T, S);
    ^~~~~~~~~~~~~~~~
/Users/dan/.node-gyp/4.0.0/deps/v8/include/v8.h:180:37: note: expanded from macro 'TYPE_CHECK'
    *(static_cast<T* volatile*>(0)) = static_cast<S*>(0);      \
                                    ^ ~~~~~~~~~~~~~~~~~~
../../nan/nan.h:423:12: note: in instantiation of function template specialization
      'v8::Local<v8::Boolean>::Local<v8::Value>' requested here
    return NanEscapeScope(NanNew(v8::True(v8::Isolate::GetCurrent())));
           ^
../../nan/nan.h:397:30: note: expanded from macro 'NanEscapeScope'
# define NanEscapeScope(val) scope.Escape(_NanEnsureLocal(val))
                             ^
In file included from ../src/main.cc:1:
In file included from ../../nan/nan.h:24:
In file included from /Users/dan/.node-gyp/4.0.0/src/node.h:42:
/Users/dan/.node-gyp/4.0.0/deps/v8/include/v8.h:221:5: error: assigning to 'v8::Function *volatile' from incompatible
      type 'v8::Value *'
    TYPE_CHECK(T, S);
    ^~~~~~~~~~~~~~~~
/Users/dan/.node-gyp/4.0.0/deps/v8/include/v8.h:180:37: note: expanded from macro 'TYPE_CHECK'
    *(static_cast<T* volatile*>(0)) = static_cast<S*>(0);      \
                                    ^ ~~~~~~~~~~~~~~~~~~
../../nan/nan.h:1513:12: note: in instantiation of function template specialization
      'v8::Local<v8::Function>::Local<v8::Value>' requested here
    return NanEscapeScope(NanNew(handle)->Get(kCallbackIndex)
           ^
../../nan/nan.h:397:30: note: expanded from macro 'NanEscapeScope'
# define NanEscapeScope(val) scope.Escape(_NanEnsureLocal(val))
                             ^
In file included from ../src/main.cc:1:
In file included from ../../nan/nan.h:24:
In file included from /Users/dan/.node-gyp/4.0.0/src/node.h:42:
/Users/dan/.node-gyp/4.0.0/deps/v8/include/v8.h:221:5: error: assigning to 'v8::Object *volatile' from incompatible
      type 'v8::Value *'
    TYPE_CHECK(T, S);
    ^~~~~~~~~~~~~~~~
/Users/dan/.node-gyp/4.0.0/deps/v8/include/v8.h:180:37: note: expanded from macro 'TYPE_CHECK'
    *(static_cast<T* volatile*>(0)) = static_cast<S*>(0);      \
                                    ^ ~~~~~~~~~~~~~~~~~~
../../nan/nan.h:1631:12: note: in instantiation of function template specialization
      'v8::Local<v8::Object>::Local<v8::Value>' requested here
    return NanEscapeScope(handle->Get(NanNew(key)).As<v8::Object>());
           ^
../../nan/nan.h:397:30: note: expanded from macro 'NanEscapeScope'
# define NanEscapeScope(val) scope.Escape(_NanEnsureLocal(val))
                             ^
9 errors generated.
make: *** [Release/obj.target/runas/src/main.o] Error 1
gyp ERR! build error
gyp ERR! stack Error: `make` failed with exit code: 2
gyp ERR! stack     at ChildProcess.onExit (/usr/local/lib/node_modules/npm/node_modules/node-gyp/lib/build.js:269:23)
gyp ERR! stack     at emitTwo (events.js:87:13)
gyp ERR! stack     at ChildProcess.emit (events.js:172:7)
gyp ERR! stack     at Process.ChildProcess._handle.onexit (internal/child_process.js:200:12)
gyp ERR! System Darwin 14.5.0
gyp ERR! command "/usr/local/bin/iojs" "/usr/local/lib/node_modules/npm/node_modules/node-gyp/bin/node-gyp.js" "rebuild"
gyp ERR! cwd /Users/dan/stuff/text-buffer/node_modules/pathwatcher/node_modules/runas
gyp ERR! node -v v4.0.0
gyp ERR! node-gyp -v v2.0.2
gyp ERR! not ok

> [email protected] install /Users/dan/stuff/text-buffer/node_modules/grunt-coffeelint/node_modules/coffeelint
> [ -e lib/commandline.js ] || npm run compile

npm ERR! Darwin 14.5.0
npm ERR! argv "/usr/local/bin/iojs" "/usr/local/bin/npm" "install"
npm ERR! node v4.0.0
npm ERR! npm  v2.14.3
npm ERR! code ELIFECYCLE

npm ERR! [email protected] install: `node-gyp rebuild`
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the [email protected] install script 'node-gyp rebuild'.
npm ERR! This is most likely a problem with the runas package,
npm ERR! not with npm itself.
npm ERR! Tell the author that this fails on your system:
npm ERR!     node-gyp rebuild
npm ERR! You can get their info via:
npm ERR!     npm owner ls runas
npm ERR! There is likely additional logging output above.

npm ERR! Please include the following file with any support request:
npm ERR!     /Users/dan/stuff/text-buffer/npm-debug.log

Random MarkerIndex mutation spec failure

Originally reported by @as-cii. Seed: 1432630912048. Output:

MarkerIndex
  randomized mutations
    it maintains data structure invariants and returns correct query results
      Expected { row : 16, column : 4 } to equal { row : 9, column : 9 }, '(Marker 12 start; Seed: 1432630912048)'. (spec/marker-index-spec.coffee:330:46)
      Expected set (15 16 4) to have item 12. (Seed: 1432630912048) (spec/marker-index-spec.coffee:336:70)
      Expected set (15 16 4) to have item 12. (Seed: 1432630912048) (spec/marker-index-spec.coffee:336:70)
      Expected set (15 16 4) to have item 12. (Seed: 1432630912048) (spec/marker-index-spec.coffee:336:70)
      Expected set (15 16 4) to have item 12. (Seed: 1432630912048) (spec/marker-index-spec.coffee:336:70)
      Expected set (15 16 4) to have item 12. (Seed: 1432630912048) (spec/marker-index-spec.coffee:336:70)
      Expected set (15) to have item 12. (Seed: 1432630912048) (spec/marker-index-spec.coffee:336:70)

Undo tree

Just wondering if an undo tree is available in atom.
undoing
And if not, could I start implementing a branching history for Undo/Redo?

applyChange emits lots of events when calling `replace`

More of a question than an issue necessarily.

I noticed when playing around the whitespace's "Convert tabs/spaces to spaces/tabs" functionality that the pane would hang for 3-4 seconds at a time for a decently sized file (say text-buffer.coffee and its 1400 lines of code). After looking at a flame graph and digging into the code, I realized a lot of this time is spent on @emitter.emit calls originating from applyChange being called for each regex replacement (in this case replacing tabs with spaces or vice versa). Specifically, each call to applyChange emits a will-change (which happened to have one listener on my machine), and a did-change listener (which has 4 listeners locally). Disabling the emit events took the run time down to around a third of a second, or about a tenth of the original run time.

Is there a reason why we need to emit so many events in this particular scenario? Would it make sense for calls to replace or even transact to only emit the change events once before and once after all the replacements have concluded? If so, how might that look?

I can post some screenshots to clarify the issue if necessary. Thanks!

Error on copy

Whenever I try to copy text (Ctrl+C), I get this error:
Uncaught TypeError: Cannot call method 'split' of undefined c:\Program Files (x86)\Atom\resources\app\node_modules\text-buffer\lib\range.js:48
This only happens on my Windows machine at work, works as expected on OS X.
What I find weird is that I don't have this problem when I cut text (Ctrl+X).

Had a look through the file throwing the error, and just seems like it can't find the helpers.js file, presumably a problem with how Windows handles file paths, as opposed to Unix-based systems.

Reloading doesn't effectly reload the file in the buffer

In Atom 1.3.2 (also in 1.0.2) and probably other versions as well, there is a "reload" option in the "View" menu.

Expected behavior:

You have a text file opened in the buffer. Modify the file. Reload the file (ctrl + alt + r), there is a warning saying "File has changes, do you want to save them? Your changes will be lost if you close this item without saving.". After the reload, the file should be back to its initial state (the one saved on the disk).

Current behavior:

After the reload, the buffer is still in the modified state (with a blue dot indicating the buffer was changed). It hasn't reloaded at all.

In addition, the warning message is not accurate: when we reload the tabs, we don't expect to "close this item" but to reload it.

dedicated key-binding for "Auto Indented Paste"?

I'm not even sure this is the right place to put this, but this is the one feature I miss the most from Sublime.

Not auto-indent on paste, but rather a dedicated key-binding to do that selectively.

Node.dump has very, very deep recursion

I am tracing down some performance issues in atom when dealing with very large files, and they have led me to Node.dump inside of marker-index having incredibly deep recursive calls (on the order of 12.5k calls from a single keystroke on an 8k line file).

image

If there is some documentation around the overall ideas behind text-buffer, I'd love to take a look so I can attempt to remedy this bottleneck.

Rename repo to text-buffer?

Having the -core suffix makes me think this repo isn't usable without standalone but it is right?

If someone uses this as a module they will have a fully functional text-buffer and won't have to implement any methods themselves?

Uncaught TypeError: Cannot read property 'length' of null

Uncaught TypeError: Cannot read property 'length' of null /Applications/Atom.app/Contents/Resources/app/node_modules/text-buffer/lib/history.js:100

mac os x: 10.9.4
atom: 0.125.0

Also, I try to debug and print the error stack:

TypeError
 "TypeError: Cannot read property 'length' of null
  at Marker.module.exports.Marker.resumeChangeEvents (/Applications/Atom.app/Contents/Resources/app/node_modules/text-buffer/lib/marker.js:558:47)
  at MarkerManager.module.exports.MarkerManager.resumeChangeEvents (/Applications/Atom.app/Contents/Resources/app/node_modules/text-buffer/lib/marker-manager.js:235:30)
  at TextBuffer.module.exports.TextBuffer.applyPatch (/Applications/Atom.app/Contents/Resources/app/node_modules/text-buffer/lib/text-buffer.js:448:15)
  at TextBuffer.module.exports.TextBuffer.setTextInRange (/Applications/Atom.app/Contents/Resources/app/node_modules/text-buffer/lib/text-buffer.js:322:12)
  at Editor.module.exports.Editor.setIndentationForBufferRow (/Applications/Atom.app/Contents/Resources/app/src/editor.js:1033:26)
  at LanguageMode.module.exports.LanguageMode.autoDecreaseIndentForBufferRow (/Applications/Atom.app/Contents/Resources/app/src/language-mode.js:394:28)
  at Editor._results.push._this.(anonymous function) [as autoDecreaseIndentForBufferRow] (/Applications/Atom.app/Contents/Resources/app/node_modules/delegato/lib/delegator.js:67:61)
  at Selection.module.exports.Selection.insertText (/Applications/Atom.app/Contents/Resources/app/src/selection.js:478:21)
  at /Applications/Atom.app/Contents/Resources/app/src/editor.js:807:31
  at /Applications/Atom.app/Contents/Resources/app/src/editor.js:502:27
  at History.module.exports.History.transact (/Applications/Atom.app/Contents/Resources/app/node_modules/text-buffer/lib/history.js:90:18)
  at TextBuffer.module.exports.TextBuffer.transact (/Applications/Atom.app/Contents/Resources/app/node_modules/text-buffer/lib/text-buffer.js:1020:27)
  at Editor.module.exports.Editor.transact (/Applications/Atom.app/Contents/Resources/app/src/editor.js:1104:26)
  at Editor.module.exports.Editor.mutateSelectedText (/Applications/Atom.app/Contents/Resources/app/src/editor.js:495:19)
  at Editor.module.exports.Editor.insertText (/Applications/Atom.app/Contents/Resources/app/src/editor.js:804:21)
  at Editor.object.(anonymous function) [as insertText] (/Applications/Atom.app/Contents/Resources/app/node_modules/underscore-plus/lib/underscore-plus.js:55:27)
  at [object Object].module.exports.React.createClass.onTextInput (/Applications/Atom.app/Contents/Resources/app/src/editor-component.js:870:18)
  at HTMLDivElement.boundMethod (/Applications/Atom.app/Contents/Resources/app/node_modules/react-atom-fork/lib/ReactCompositeComponent.js:1295:21)

This is how to reproduce the bug:
bug

detectEncoding such as the one in encoding-selector

encoding-selector package has a function to detect encoding.
But I think that if text-buffer has the function, the implementation will become more reasonable and 'File Encoding' setting may have 'auto detect' option.

Enhancement: Saving a read-only file

Saving a read-only file in Atom is not possible, it results in an error (Atom Issue #9056). I looked into implementing such a feature, text-buffer seems to be a good place. Please take a look at my implementation. My question is:

  1. Is text-buffer an appropriate place for this functionality?
  2. I would like to avoid checking the read-only attribute prior to every save operation, which is why my implementation does this when a save fails. This works quite well, the only problem being that the error message in Atom is still visible. I don't see any obvious/clean way of suppressing this error message. If anyone has an idea, please let me know.

Add encoding support

For effective implementation of atom/atom#1806 we will need alternate encoding support in text-buffer project.

IMO it should be able to get encoding from the constructor params, read file with this encoding and remember it so it can save file with the same encoding it was read with. Also it should be optional encoding parameter for the save function so caller may override the encoding on save.

We could also add automatic encoding detection feature in future.

Collapse compiler directive ifs

It would be nice if we were able to collapse #ifdef and #ifndef directives, like we can regular methods and if statements, as shown below:
#ifdef compiler directive

Document public fields of Range and Point.

Currently, from the docs for Point and Range, it is unclear how to read the values of those types. The public fields row, column, start, and end need to be documented.

Also, it should be clarified whether they are mutable or immutable. The copy() and freeze() methods suggest that both types are mutable, though I do not believe that is the intention.

`backwardsScan` + `replace` produces incorrect results

Hi,

In javascript, the classic string replace function works as follows:

"foo \n bar \r\n baz".replace(/\r?\n/g, '\r\n')
> "foo \r\n bar \r\n baz"

whereas with TextBuffer the result is as follows:

buffer = new TextBuffer("foo \n bar \r\n baz")
buffer.backwardsScan( /\r?\n/g, match => match.replace('\r\n') )
> "foo \n bar \n baz"

(...even more interesting things happen when replacing /$/g)

I have found this issue as I was exploring why suddenly my editorconfig stopped working in sindresorhus/atom-editorconfig#54

Can someone please have a look at this or help me understand if my issue with editorconfig is related to this.

[QUESTION]: How can a plugin instantiate a `Point` ?

Please apologize using the ticket system to ask a question - if there are better ways, I'd be glad to hear about them to use them in the future.

Even though points are returned by the API, I am having trouble finding the standard way of instantiating this type myself. I need to do this as part of my unit-tests for the plugin I am writing.

Thank you

Support out-of-bounds selection.

In order for proper columnar selection to be implemented, you need to be able to highlight invalid regions. Right now all selection gets clipped to valid regions which makes implementing blockwise/columnar selection difficult.

Thoughts?

Painfully slow removal of trailing whitespace on save of large files

Problem description

If one tries to save a large file with atom, the save is performed asynchronously, and if it is configured to remove trailing whitespace, it will block the entire editor for a painfully long time.

Very often I will have a large JSON file open and out of the practice of good habit, I will regularly hit meta-s to save the file. I will then be forced to take a stroll as the entire renderer window will be blocked for what is often a minute or so.

Today I finally performed a profile of the issue and nailed down the cause.
Here is the result for the reload of a large file (~150,000 lines).
Profiling Result

Suggested changes

Fix Regex

Execution

I'll take a look at this tonight.

Remove hard dependency on pathwatcher.File

It would be great if the API of pathwatcher.File that TextBuffer needs could be abstracted out into its own interface, say TextSource. Then TextBuffer could depend on the TextSource interface, which could have multiple implementations. Obviously pathwatcher.File would implement TextSource by default, but it would also be possible to supply a TextSource for content that is not stored locally. (Obviously, async APIs would be preferred in that scenario.)

I would be happy to submit a patch for such a refactoring. Are there any examples of how to declare an interface in Atom?

Random MarkerIndex spec failure

Random seed: 1438117651498

MarkerIndex
  randomized mutations
    it maintains data structure invariants and returns correct query results
      Expected { row : 18, column : 6 } to equal { row : 11, column : 12 }, '(Marker 9 start; Seed: 1438117651498)'. (spec/marker-index-spec.coffee:341:46)
      Expected { row : 18, column : 6 } to equal { row : 11, column : 12 }, '(Marker 11 start; Seed: 1438117651498)'. (spec/marker-index-spec.coffee:341:46)
      Expected set (10 13 14 15 16) to have item 11. (Seed: 1438117651498) (spec/marker-index-spec.coffee:347:70)
      Expected set (10 14 15 16) to have item 11. (Seed: 1438117651498) (spec/marker-index-spec.coffee:347:70)
      Expected set (10 13 14 15 16) to have item 11. (Seed: 1438117651498) (spec/marker-index-spec.coffee:347:70)
      Expected set (10 14 15 16) to have item 11. (Seed: 1438117651498) (spec/marker-index-spec.coffee:347:70)

/cc @maxbrunsfeld

Multiple selection copy-paste does not behave properly

When editing multiple lines at once (via multiple cursors), copying and then pasting behaves as pasting a solid block (of all selected text) and inserting it multiple times. Behaviour should be to paste each k'th item at the k'th cursor as in Sublime Text.

This could easily be done by splitting at line breaks and associating each break to each cursor.

If this is the wrong module to post this to, please direct me to the proper one, I scrolled through all the modules and this seemed like the proper one.

Get EOL

There currently is no publicly available API to get the buffer's EOL character from a package. The current getPreferredLineEnding() method returns null for my editor, which is using the default line endings. Can the get method be updated to return the correct character type every time?

Document buffer not being updated correctly

Certain files opened in Atom, after being updated externally, will exhibit an odd behavior, wherein the selection within the document is offset/incorrectly calculated.

Fiddling with the find-and-replace pane also yields peculiar results:
atom bug - selection offset

It also seems like the data representation isn't working as it should:
atom bug - document content

I later noticed that the encoding wasn't set as it should be (UTF-16 LE instead of UTF-8):
atom bug - encoding

If I am not mistaken, I believe that the BOM header was displayed until I changed the encoding:
atom bug - bom header

Sorry about all the fuzziness; since this behavior occurs very rarely and as I'm not fully aware of how it is triggered, I wouldn't have been able to reproduce it in safe mode.

Should this issue happen to be unrelated this component, please point me toward the right direction.

Atom version: 0.182.0 (I hadn't yet updated to the latest version on this machine, and couldn't afford to update as I didn't want to risk not being able to reproduce it)
Operating system: Windows 7 64-bit

Improve history serialization and persistence

@as-cii I wanted to some up some of my thoughts on history serialization in case you're interested. Here's a potential set of steps that I think could put is in a better spot both design-wise and in terms of performance.

Compact Binary Patch Format

  • Switch the undo/redo stack to store patches rather than the current list of temporally-ordered changes.
  • Implement Patch.prototype.compact that converts the internal representation of the patch from a tree to a flat buffer. This format would only support getChanges by directly iterating the serialized data, which is easy with that library. Call this method at the end of each transaction to keep the history in a memory-efficient way.
  • Implement Patch.prototype.serialize in terms of the same buffer format.

It might make more sense to just serialize patches to buffers before storing them in the history and deserializing them on an as-needed basis. The compact approach where you actually store Patch instances with a different backing store just seemed cool in that it maintains a nice programmatic interface, but it may be more trouble than it's worth in other ways.

Incremental Persistence

I'm still concerned about repeatedly serializing the same history over and over again. It might not be a big deal once it's smaller, but if it is, I have this idea for incrementally persisting the state.

  • Create a global buffer pool in IndexedDB... We'd store opened buffers in a single pool, regardless of window or project with a key scheme like atom::buffers::/path/to/buffer.txt (there may be precedent for the key delimiter so we should research).
  • Associated with each buffer could be its modified text in a record at atom::buffers::/path/to/buffer.txt::modifiedContents
  • Also associated with each buffer could be an undo and redo stack, stored via lexicographically-sorted keys as follows: atom::buffers::/path/to/buffer.txt::undo::1, atom::buffers::/path/to/buffer.txt::undo::2, atom::buffers::/path/to/buffer.txt::undo::3, etc. If you pop an undo entry, delete its record. If you build a new undo entry, increment the integer in the key. (You might actually want to decouple the undo and redo entry keys from the buffer's path and just synthesize an id that you reference from the path once to simplify rename.)

It may be that the history never gets big enough to require this, but it would be a cool scheme for basically associate an infinite history with any file on disk in a persistent way. I think it might be pretty cool.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.