mirror of
				https://gitee.com/gitea/gitea
				synced 2025-11-04 08:30:25 +08:00 
			
		
		
		
	On showing diff/file, use the tab_width specified on .editorconfig, if any (#3241)
Closes #3182
This commit is contained in:
		@@ -6,10 +6,12 @@ package context
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
	"fmt"
 | 
						"fmt"
 | 
				
			||||||
 | 
						"io/ioutil"
 | 
				
			||||||
	"path"
 | 
						"path"
 | 
				
			||||||
	"strings"
 | 
						"strings"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"github.com/Unknwon/com"
 | 
						"github.com/Unknwon/com"
 | 
				
			||||||
 | 
						"gopkg.in/editorconfig/editorconfig-core-go.v1"
 | 
				
			||||||
	"gopkg.in/macaron.v1"
 | 
						"gopkg.in/macaron.v1"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"github.com/gogits/git-module"
 | 
						"github.com/gogits/git-module"
 | 
				
			||||||
@@ -69,6 +71,28 @@ func (r *Repository) HasAccess() bool {
 | 
				
			|||||||
	return r.AccessMode >= models.ACCESS_MODE_READ
 | 
						return r.AccessMode >= models.ACCESS_MODE_READ
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// GetEditorconfig returns the .editorconfig definition if found in the
 | 
				
			||||||
 | 
					// HEAD of the default repo branch.
 | 
				
			||||||
 | 
					func (r *Repository) GetEditorconfig() (*editorconfig.Editorconfig, error) {
 | 
				
			||||||
 | 
						commit, err := r.GitRepo.GetBranchCommit(r.Repository.DefaultBranch)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						treeEntry, err := commit.GetTreeEntryByPath(".editorconfig")
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						reader, err := treeEntry.Blob().Data()
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						data, err := ioutil.ReadAll(reader)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return editorconfig.ParseBytes(data)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func RetrieveBaseRepo(ctx *Context, repo *models.Repository) {
 | 
					func RetrieveBaseRepo(ctx *Context, repo *models.Repository) {
 | 
				
			||||||
	// Non-fork repository will not return error in this method.
 | 
						// Non-fork repository will not return error in this method.
 | 
				
			||||||
	if err := repo.GetBaseRepo(); err != nil {
 | 
						if err := repo.GetBaseRepo(); err != nil {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -17,6 +17,7 @@ import (
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	"golang.org/x/net/html/charset"
 | 
						"golang.org/x/net/html/charset"
 | 
				
			||||||
	"golang.org/x/text/transform"
 | 
						"golang.org/x/text/transform"
 | 
				
			||||||
 | 
						"gopkg.in/editorconfig/editorconfig-core-go.v1"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"github.com/gogits/gogs/models"
 | 
						"github.com/gogits/gogs/models"
 | 
				
			||||||
	"github.com/gogits/gogs/modules/base"
 | 
						"github.com/gogits/gogs/modules/base"
 | 
				
			||||||
@@ -109,6 +110,15 @@ func NewFuncMap() []template.FuncMap {
 | 
				
			|||||||
			mimeType := mime.TypeByExtension(filepath.Ext(filename))
 | 
								mimeType := mime.TypeByExtension(filepath.Ext(filename))
 | 
				
			||||||
			return strings.HasPrefix(mimeType, "image/")
 | 
								return strings.HasPrefix(mimeType, "image/")
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
 | 
							"TabSizeClass": func(ec *editorconfig.Editorconfig, filename string) string {
 | 
				
			||||||
 | 
								if ec != nil {
 | 
				
			||||||
 | 
									def := ec.GetDefinitionForFilename(filename)
 | 
				
			||||||
 | 
									if def.TabWidth > 0 {
 | 
				
			||||||
 | 
										return fmt.Sprintf("tab-size-%d", def.TabWidth)
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								return "tab-size-8"
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
	}}
 | 
						}}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -2312,6 +2312,70 @@ footer .ui.language .menu {
 | 
				
			|||||||
#delete-repo-modal .ui.message {
 | 
					#delete-repo-modal .ui.message {
 | 
				
			||||||
  width: 100%!important;
 | 
					  width: 100%!important;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					.tab-size-1 {
 | 
				
			||||||
 | 
					  tab-size: 1 !important;
 | 
				
			||||||
 | 
					  -moz-tab-size: 1 !important;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					.tab-size-2 {
 | 
				
			||||||
 | 
					  tab-size: 2 !important;
 | 
				
			||||||
 | 
					  -moz-tab-size: 2 !important;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					.tab-size-3 {
 | 
				
			||||||
 | 
					  tab-size: 3 !important;
 | 
				
			||||||
 | 
					  -moz-tab-size: 3 !important;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					.tab-size-4 {
 | 
				
			||||||
 | 
					  tab-size: 4 !important;
 | 
				
			||||||
 | 
					  -moz-tab-size: 4 !important;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					.tab-size-5 {
 | 
				
			||||||
 | 
					  tab-size: 5 !important;
 | 
				
			||||||
 | 
					  -moz-tab-size: 5 !important;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					.tab-size-6 {
 | 
				
			||||||
 | 
					  tab-size: 6 !important;
 | 
				
			||||||
 | 
					  -moz-tab-size: 6 !important;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					.tab-size-7 {
 | 
				
			||||||
 | 
					  tab-size: 7 !important;
 | 
				
			||||||
 | 
					  -moz-tab-size: 7 !important;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					.tab-size-8 {
 | 
				
			||||||
 | 
					  tab-size: 8 !important;
 | 
				
			||||||
 | 
					  -moz-tab-size: 8 !important;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					.tab-size-9 {
 | 
				
			||||||
 | 
					  tab-size: 9 !important;
 | 
				
			||||||
 | 
					  -moz-tab-size: 9 !important;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					.tab-size-10 {
 | 
				
			||||||
 | 
					  tab-size: 10 !important;
 | 
				
			||||||
 | 
					  -moz-tab-size: 10 !important;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					.tab-size-11 {
 | 
				
			||||||
 | 
					  tab-size: 11 !important;
 | 
				
			||||||
 | 
					  -moz-tab-size: 11 !important;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					.tab-size-12 {
 | 
				
			||||||
 | 
					  tab-size: 12 !important;
 | 
				
			||||||
 | 
					  -moz-tab-size: 12 !important;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					.tab-size-13 {
 | 
				
			||||||
 | 
					  tab-size: 13 !important;
 | 
				
			||||||
 | 
					  -moz-tab-size: 13 !important;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					.tab-size-14 {
 | 
				
			||||||
 | 
					  tab-size: 14 !important;
 | 
				
			||||||
 | 
					  -moz-tab-size: 14 !important;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					.tab-size-15 {
 | 
				
			||||||
 | 
					  tab-size: 15 !important;
 | 
				
			||||||
 | 
					  -moz-tab-size: 15 !important;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					.tab-size-16 {
 | 
				
			||||||
 | 
					  tab-size: 16 !important;
 | 
				
			||||||
 | 
					  -moz-tab-size: 16 !important;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
.organization {
 | 
					.organization {
 | 
				
			||||||
  padding-top: 15px;
 | 
					  padding-top: 15px;
 | 
				
			||||||
  padding-bottom: 80px;
 | 
					  padding-bottom: 80px;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1360,3 +1360,13 @@
 | 
				
			|||||||
		width: 100%!important;
 | 
							width: 100%!important;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// generate .tab-size-{i} from 1 to 16
 | 
				
			||||||
 | 
					.generate-tab-size(16);
 | 
				
			||||||
 | 
					.generate-tab-size(@n, @i: 1) when (@i =< @n) {
 | 
				
			||||||
 | 
						.tab-size-@{i} {
 | 
				
			||||||
 | 
							tab-size: @i !important;
 | 
				
			||||||
 | 
							-moz-tab-size: @i !important;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						.generate-tab-size(@n, (@i + 1));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -174,6 +174,13 @@ func Diff(ctx *context.Context) {
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ec, err := ctx.Repo.GetEditorconfig()
 | 
				
			||||||
 | 
						if err != nil && !git.IsErrNotExist(err) {
 | 
				
			||||||
 | 
							ctx.Handle(500, "ErrGettingEditorconfig", err)
 | 
				
			||||||
 | 
							return
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						ctx.Data["Editorconfig"] = ec
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ctx.Data["CommitID"] = commitID
 | 
						ctx.Data["CommitID"] = commitID
 | 
				
			||||||
	ctx.Data["IsSplitStyle"] = ctx.Query("style") == "split"
 | 
						ctx.Data["IsSplitStyle"] = ctx.Query("style") == "split"
 | 
				
			||||||
	ctx.Data["Username"] = userName
 | 
						ctx.Data["Username"] = userName
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -371,6 +371,13 @@ func ViewPullFiles(ctx *context.Context) {
 | 
				
			|||||||
		return
 | 
							return
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ec, err := ctx.Repo.GetEditorconfig()
 | 
				
			||||||
 | 
						if err != nil && !git.IsErrNotExist(err) {
 | 
				
			||||||
 | 
							ctx.Handle(500, "ErrGettingEditorconfig", err)
 | 
				
			||||||
 | 
							return
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						ctx.Data["Editorconfig"] = ec
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	headTarget := path.Join(pull.HeadUserName, pull.HeadRepo.Name)
 | 
						headTarget := path.Join(pull.HeadUserName, pull.HeadRepo.Name)
 | 
				
			||||||
	ctx.Data["IsSplitStyle"] = ctx.Query("style") == "split"
 | 
						ctx.Data["IsSplitStyle"] = ctx.Query("style") == "split"
 | 
				
			||||||
	ctx.Data["Username"] = pull.HeadUserName
 | 
						ctx.Data["Username"] = pull.HeadUserName
 | 
				
			||||||
@@ -623,6 +630,13 @@ func CompareAndPullRequest(ctx *context.Context) {
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ec, err := ctx.Repo.GetEditorconfig()
 | 
				
			||||||
 | 
						if err != nil && !git.IsErrNotExist(err) {
 | 
				
			||||||
 | 
							ctx.Handle(500, "ErrGettingEditorconfig", err)
 | 
				
			||||||
 | 
							return
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						ctx.Data["Editorconfig"] = ec
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ctx.HTML(200, COMPARE_PULL)
 | 
						ctx.HTML(200, COMPARE_PULL)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -225,6 +225,12 @@ func Home(ctx *context.Context) {
 | 
				
			|||||||
	ctx.Data["Username"] = userName
 | 
						ctx.Data["Username"] = userName
 | 
				
			||||||
	ctx.Data["Reponame"] = repoName
 | 
						ctx.Data["Reponame"] = repoName
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ec, err := ctx.Repo.GetEditorconfig()
 | 
				
			||||||
 | 
						if err != nil && !git.IsErrNotExist(err) {
 | 
				
			||||||
 | 
							ctx.Handle(500, "ErrGettingEditorconfig", err)
 | 
				
			||||||
 | 
							return
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						ctx.Data["Editorconfig"] = ec
 | 
				
			||||||
	var treenames []string
 | 
						var treenames []string
 | 
				
			||||||
	paths := make([]string, 0)
 | 
						paths := make([]string, 0)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -53,7 +53,7 @@
 | 
				
			|||||||
			</div>
 | 
								</div>
 | 
				
			||||||
		{{else}}
 | 
							{{else}}
 | 
				
			||||||
			{{$highlightClass := $file.GetHighlightClass}}
 | 
								{{$highlightClass := $file.GetHighlightClass}}
 | 
				
			||||||
			<div class="diff-file-box diff-box file-content" id="diff-{{.Index}}">
 | 
								<div class="diff-file-box diff-box file-content {{TabSizeClass $.Editorconfig $file.Name}}" id="diff-{{.Index}}">
 | 
				
			||||||
				<h4 class="ui top attached normal header">
 | 
									<h4 class="ui top attached normal header">
 | 
				
			||||||
					<div class="diff-counter count ui left">
 | 
										<div class="diff-counter count ui left">
 | 
				
			||||||
						{{if $file.IsBin}}
 | 
											{{if $file.IsBin}}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,4 +1,4 @@
 | 
				
			|||||||
<div id="file-content">
 | 
					<div id="file-content" class="{{TabSizeClass .Editorconfig .FileName}}">
 | 
				
			||||||
	<h4 class="ui top attached header" id="{{if .ReadmeExist}}repo-readme{{else}}repo-read-file{{end}}">
 | 
						<h4 class="ui top attached header" id="{{if .ReadmeExist}}repo-readme{{else}}repo-read-file{{end}}">
 | 
				
			||||||
		{{if .ReadmeExist}}
 | 
							{{if .ReadmeExist}}
 | 
				
			||||||
			<i class="book icon ui left"></i>
 | 
								<i class="book icon ui left"></i>
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user