mirror of
https://github.com/zyedidia/micro.git
synced 2026-03-30 06:37:14 +09:00
@@ -1,9 +1,5 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
|
||||||
"strings"
|
|
||||||
)
|
|
||||||
|
|
||||||
// FromCharPos converts from a character position to an x, y position
|
// FromCharPos converts from a character position to an x, y position
|
||||||
func FromCharPos(loc int, buf *Buffer) (int, int) {
|
func FromCharPos(loc int, buf *Buffer) (int, int) {
|
||||||
return FromCharPosStart(0, 0, 0, loc, buf)
|
return FromCharPosStart(0, 0, 0, loc, buf)
|
||||||
@@ -357,13 +353,13 @@ func (c *Cursor) GetCharPosInLine(lineNum, visualPos int) int {
|
|||||||
// Get the tab size
|
// Get the tab size
|
||||||
tabSize := int(settings["tabsize"].(float64))
|
tabSize := int(settings["tabsize"].(float64))
|
||||||
// This is the visual line -- every \t replaced with the correct number of spaces
|
// This is the visual line -- every \t replaced with the correct number of spaces
|
||||||
visualLine := strings.Replace(c.buf.Lines[lineNum], "\t", "\t"+Spaces(tabSize-1), -1)
|
visualLineLen := StringWidth(c.buf.Lines[lineNum])
|
||||||
if visualPos > Count(visualLine) {
|
if visualPos > visualLineLen {
|
||||||
visualPos = Count(visualLine)
|
visualPos = visualLineLen
|
||||||
}
|
}
|
||||||
numTabs := NumOccurences(visualLine[:visualPos], '\t')
|
width := WidthOfLargeRunes(c.buf.Lines[lineNum])
|
||||||
if visualPos >= (tabSize-1)*numTabs {
|
if visualPos >= width {
|
||||||
return visualPos - (tabSize-1)*numTabs
|
return visualPos - width
|
||||||
}
|
}
|
||||||
return visualPos / tabSize
|
return visualPos / tabSize
|
||||||
}
|
}
|
||||||
@@ -371,8 +367,7 @@ func (c *Cursor) GetCharPosInLine(lineNum, visualPos int) int {
|
|||||||
// GetVisualX returns the x value of the cursor in visual spaces
|
// GetVisualX returns the x value of the cursor in visual spaces
|
||||||
func (c *Cursor) GetVisualX() int {
|
func (c *Cursor) GetVisualX() int {
|
||||||
runes := []rune(c.buf.Lines[c.Y])
|
runes := []rune(c.buf.Lines[c.Y])
|
||||||
tabSize := int(settings["tabsize"].(float64))
|
return StringWidth(string(runes[:c.X]))
|
||||||
return c.X + NumOccurences(string(runes[:c.X]), '\t')*(tabSize-1)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Relocate makes sure that the cursor is inside the bounds of the buffer
|
// Relocate makes sure that the cursor is inside the bounds of the buffer
|
||||||
|
|||||||
@@ -7,6 +7,8 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
"unicode/utf8"
|
"unicode/utf8"
|
||||||
|
|
||||||
|
"github.com/mattn/go-runewidth"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Util.go is a collection of utility functions that are used throughout
|
// Util.go is a collection of utility functions that are used throughout
|
||||||
@@ -138,6 +140,28 @@ func GetModTime(path string) (time.Time, bool) {
|
|||||||
return info.ModTime(), true
|
return info.ModTime(), true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func StringWidth(str string) int {
|
||||||
|
sw := runewidth.StringWidth(str)
|
||||||
|
sw += NumOccurences(str, '\t') * (int(settings["tabsize"].(float64)) - 1)
|
||||||
|
return sw
|
||||||
|
}
|
||||||
|
|
||||||
|
func WidthOfLargeRunes(str string) int {
|
||||||
|
count := 0
|
||||||
|
for _, ch := range str {
|
||||||
|
var w int
|
||||||
|
if ch == '\t' {
|
||||||
|
w = int(settings["tabsize"].(float64))
|
||||||
|
} else {
|
||||||
|
w = runewidth.RuneWidth(ch)
|
||||||
|
}
|
||||||
|
if w > 1 {
|
||||||
|
count += (w - 1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return count
|
||||||
|
}
|
||||||
|
|
||||||
func runePos(p int, str string) int {
|
func runePos(p int, str string) int {
|
||||||
return utf8.RuneCountInString(str[:p])
|
return utf8.RuneCountInString(str[:p])
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/mattn/go-runewidth"
|
||||||
"github.com/zyedidia/tcell"
|
"github.com/zyedidia/tcell"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -601,6 +602,16 @@ func (v *View) DisplayView() {
|
|||||||
screen.SetContent(x-v.leftCol, lineN, ' ', nil, lineStyle)
|
screen.SetContent(x-v.leftCol, lineN, ' ', nil, lineStyle)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else if runewidth.RuneWidth(ch) > 1 {
|
||||||
|
if x-v.leftCol >= v.lineNumOffset {
|
||||||
|
screen.SetContent(x-v.leftCol, lineN, ch, nil, lineStyle)
|
||||||
|
}
|
||||||
|
for i := 0; i < runewidth.RuneWidth(ch)-1; i++ {
|
||||||
|
x++
|
||||||
|
if x-v.leftCol >= v.lineNumOffset {
|
||||||
|
screen.SetContent(x-v.leftCol, lineN, ' ', nil, lineStyle)
|
||||||
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
if x-v.leftCol >= v.lineNumOffset {
|
if x-v.leftCol >= v.lineNumOffset {
|
||||||
screen.SetContent(x-v.leftCol, lineN, ch, nil, lineStyle)
|
screen.SetContent(x-v.leftCol, lineN, ch, nil, lineStyle)
|
||||||
|
|||||||
Reference in New Issue
Block a user