Add option for very accurate dirty flag

Set the `fastdirty` option flag to off if you really want accurate
reporting on whether the buffer is modified. This is more resource
intensive but it can be useful for people who don't mind.

Closes #787
Closes #467
This commit is contained in:
Zachary Yedidia
2017-09-17 23:33:18 -04:00
parent 19dc9d7bbc
commit fb980bb695
7 changed files with 65 additions and 18 deletions

View File

@@ -2,6 +2,7 @@ package main
import (
"bytes"
"crypto/md5"
"encoding/gob"
"io"
"io/ioutil"
@@ -57,6 +58,9 @@ type Buffer struct {
syntaxDef *highlight.Def
highlighter *highlight.Highlighter
// Hash of the original buffer -- empty if fastdirty is on
origHash [16]byte
// Buffer local settings
Settings map[string]interface{}
}
@@ -174,7 +178,7 @@ func NewBuffer(reader io.Reader, size int64, path string) *Buffer {
}
if b.Settings["saveundo"].(bool) {
// We should only use last time's eventhandler if the file wasn't by someone else in the meantime
// We should only use last time's eventhandler if the file wasn't modified by someone else in the meantime
if b.ModTime == buffer.ModTime {
b.EventHandler = buffer.EventHandler
b.EventHandler.buf = b
@@ -188,6 +192,10 @@ func NewBuffer(reader io.Reader, size int64, path string) *Buffer {
screen.EnableMouse()
}
if !b.Settings["fastdirty"].(bool) {
b.origHash = md5.Sum([]byte(b.String()))
}
b.cursors = []*Cursor{&b.Cursor}
return b
@@ -451,6 +459,13 @@ func (b *Buffer) SaveAsWithSudo(filename string) error {
return err
}
func (b *Buffer) Modified() bool {
if b.Settings["fastdirty"].(bool) {
return b.IsModified
}
return b.origHash != md5.Sum([]byte(b.String()))
}
func (b *Buffer) insert(pos Loc, value []byte) {
b.IsModified = true
b.LineArray.insert(pos, value)

File diff suppressed because one or more lines are too long

View File

@@ -1,6 +1,7 @@
package main
import (
"crypto/md5"
"encoding/json"
"errors"
"io/ioutil"
@@ -198,10 +199,13 @@ func DefaultGlobalSettings() map[string]interface{} {
"colorscheme": "default",
"cursorline": true,
"eofnewline": false,
"rmtrailingws": false,
"fastdirty": true,
"fileformat": "unix",
"ignorecase": false,
"indentchar": " ",
"infobar": true,
"mouse": true,
"rmtrailingws": false,
"ruler": true,
"savecursor": false,
"saveundo": false,
@@ -221,8 +225,6 @@ func DefaultGlobalSettings() map[string]interface{} {
},
"pluginrepos": []string{},
"useprimary": true,
"fileformat": "unix",
"mouse": true,
}
}
@@ -236,10 +238,13 @@ func DefaultLocalSettings() map[string]interface{} {
"colorcolumn": float64(0),
"cursorline": true,
"eofnewline": false,
"rmtrailingws": false,
"fastdirty": true,
"fileformat": "unix",
"filetype": "Unknown",
"ignorecase": false,
"indentchar": " ",
"mouse": true,
"rmtrailingws": false,
"ruler": true,
"savecursor": false,
"saveundo": false,
@@ -254,8 +259,6 @@ func DefaultLocalSettings() map[string]interface{} {
"tabsize": float64(4),
"tabstospaces": false,
"useprimary": true,
"fileformat": "unix",
"mouse": true,
}
}
@@ -358,6 +361,26 @@ func SetLocalOption(option, value string, view *View) error {
return err
}
if option == "fastdirty" {
// If it is being turned off, we have to hash every open buffer
var empty [16]byte
for _, tab := range tabs {
for _, v := range tab.views {
if !nativeValue.(bool) {
if v.Buf.origHash == empty {
data, err := ioutil.ReadFile(v.Buf.AbsPath)
if err != nil {
data = []byte{}
}
v.Buf.origHash = md5.Sum(data)
}
} else {
v.Buf.IsModified = v.Buf.Modified()
}
}
}
}
buf.Settings[option] = nativeValue
if option == "statusline" {

View File

@@ -20,7 +20,7 @@ func (sline *Statusline) Display() {
file := sline.view.Buf.GetName()
// If the buffer is dirty (has been modified) write a little '+'
if sline.view.Buf.IsModified {
if sline.view.Buf.Modified() {
file += " +"
}

View File

@@ -91,7 +91,7 @@ func TabbarString() (string, map[int]int) {
}
buf := t.views[t.CurView].Buf
str += buf.GetName()
if buf.IsModified {
if buf.Modified() {
str += " +"
}
if i == curTab {

View File

@@ -199,7 +199,7 @@ func (v *View) ScrollDown(n int) {
// If there are unsaved changes, the user will be asked if the view can be closed
// causing them to lose the unsaved changes
func (v *View) CanClose() bool {
if v.Type == vtDefault && v.Buf.IsModified {
if v.Type == vtDefault && v.Buf.Modified() {
var choice bool
var canceled bool
if v.Buf.Settings["autosave"].(bool) {

View File

@@ -161,6 +161,22 @@ Here are the options that you can set:
default value: `on`
* `fileformat`: this determines what kind of line endings micro will use for the file. Unix line endings
are just `\n` (lf) whereas dos line endings are `\r\n` (crlf). The two possible values for this option
are `unix` and `dos`. The fileformat will be automatically detected and displayed on the statusline but
this option is useful if you would like to change the line endings or if you are starting a new file.
default value: `unix`
* `fastdirty`: this determines what kind of algorithm micro uses to determine if a buffer is modified or
not. When `fastdirty` is on, micro just uses a boolean `modified` that is set to `true` as soon as the user
makes an edit. This is fast, but can be inaccurate. If `fastdirty` is off, then micro will hash the current
buffer against a hash of the original file (created when the buffer was loaded). This is more accurate but
obviously more resource intensive. This option is only for people who really care about having accurate
modified status.
default value: `on`
---
Default plugin options:
@@ -179,13 +195,6 @@ Default plugin options:
default value: `on`
* `fileformat`: this determines what kind of line endings micro will use for the file. Unix line endings
are just `\n` (lf) whereas dos line endings are `\r\n` (crlf). The two possible values for this option
are `unix` and `dos`. The fileformat will be automatically detected and displayed on the statusline but
this option is useful if you would like to change the line endings or if you are starting a new file.
default value: `unix`
Any option you set in the editor will be saved to the file
~/.config/micro/settings.json so, in effect, your configuration file will be
created for you. If you'd like to take your configuration with you to another